特定子域上的 Laravel 维护模式

Posted

技术标签:

【中文标题】特定子域上的 Laravel 维护模式【英文标题】:Laravel maintenance mode on specific subdomain 【发布时间】:2020-08-30 22:08:18 【问题描述】:

我知道您可以排除主应用程序的某些 URI,例如,如果您想排除 example.com/page,您只需将其添加到 CheckForMaintenanceMode.php,如下所示:

app/Http/Middleware/CheckForMaintenanceMode.php

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;

class CheckForMaintenanceMode extends Middleware

    /**
     * The URIs that should be reachable while maintenance mode is enabled.
     *
     * @var array
     */
    protected $except = [
        '/page'
    ];


现在,我的应用有几个子域使用一个应用;我的主应用程序有一个子域:app.example.com,我的 API 端点有一个子域:api.example.com,主网站:www.example.com

我怎么可能 except 特定的子域而不是维护模式的 URI?就像在维护模式下拥有 api.example.comapp.example.com 而不是主网站 www.example.com

我正在尝试自己解决这个问题,甚至制作自己的中间件只是为了做到这一点,但是是否可以使用 laravel 的内置维护模式和php artisan:down 来做到这一点?

类似:

// app.example.com and api.example.com is in maintenance mode except:

protected $except = [
    'example.com'
    'www.example.com'
];

【问题讨论】:

你不能只将'www.example.com/*' 添加到 except 数组吗? @Flame 我这样做了,它不起作用。我猜$except 对象仅适用于 URI 调查CheckForMaintenanceMode类,它调用了$request-&gt;fullUrlIs($except)函数。我还没有测试过它的内部工作原理,但我认为它应该与完整的 url 一起工作。您显然必须以不在浏览器中使用 http://localhost 的方式进行测试。 @Flame 它实际上适用于协议。请将其添加到答案中,以便我接受。谢谢。 【参考方案1】:

假设您有两个域。一是主域 另一个是子域。

mydomain.com admin.mydomain.com

您有一个页面名称维护。维护页面位于主域下。维护页面的 URL 是 mydomain.com/maintenance。 在维护模式下,您将拥有 mydomain.com/maintenance 和 admin.mydomain.com 的路由权限

现在工作流程。 转到 App\Http\Middleware 打开 PreventRequestsDuringMaintenance 中间件然后添加此代码

protected $except = [
   'maintenance*',
   'http://admin.*',
   'https://admin.*'
];

然后去 App\Exceptions 打开 Handler 文件,里面添加渲染函数

if (App::isDownForMaintenance()) 
   return redirect('/maintenance');

现在运行php artisan down

【讨论】:

【参考方案2】:

参见Illuminate\Foundation\Http\Middleware\CheckMaintenanceMode 中间件类:

它使用 Illuminate\Http\Request 类中的函数 fullUrlIs() 来检查 $except 属性的元素,该类本身调用 Str::is() 帮助器(如果您使用 Laravel 帮助器,也称为 str_is() 函数函数全局变量):

protected function inExceptArray($request)
    
        foreach ($this->except as $except) 
            if ($except !== '/') 
                $except = trim($except, '/');
            

            if ($request->fullUrlIs($except) || $request->is($except)) 
                return true;
            
        

        return false;
    

见https://laravel.com/docs/7.x/helpers#method-str-is

然后您应该能够检查这样的 url,以将该域排除在维护模式之外(即它将始终处于启动状态):

protected $except = [
    'https://www.example.com/*'
];

【讨论】:

您还必须同时包含https://www.example.com/https://www.example.com/*,以便可以访问主 URL 及其路径。

以上是关于特定子域上的 Laravel 维护模式的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 维护模式 --allow ip not working

维护模式与中间件在 Laravel 中重定向

Laravel 5.1 维护模式不起作用

如何绕过 Laravel 5 维护模式的一些 IP 地址

text Laravel维护模式,除了我的IP

如果服务器关闭,则激活维护模式