You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Laravel 11.45.0中自定义Header绕过维护模式的中间件未被调用的问题求助

Laravel 11.45.0中自定义Header绕过维护模式的中间件未被调用的问题求助

我在Laravel项目中使用如下命令启用维护模式:

php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"

为了能通过自定义HTTP头X-MAINTENANCE-BYPASS(携带和维护模式相同的密钥)绕过维护模式,我实现了一个自定义中间件。这个方案在Laravel 11.44.2中工作完全正常,但升级到11.45.0之后,这个中间件就完全没被调用了,导致头验证的逻辑根本不生效。

以下是我的实现代码:

中间件文件:app/Http/Middleware/HeaderBypassForMaintenance.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Http\MaintenanceModeBypassCookie;

class HeaderBypassForMaintenance
{
    /**
     * Handle an incoming request and allow bypassing Laravel maintenance mode
     * via a custom HTTP header (X-MAINTENANCE-BYPASS), using the same secret
     * as Laravel's native maintenance bypass.
     */
    public function handle(Request $request, Closure $next): Response
    {
        // Check if the application is currently in maintenance mode
        if (app()->isDownForMaintenance()) {
            // Get the secret token from the custom header
            $headerSecret = $request->header('X-MAINTENANCE-BYPASS');

            // Path to Laravel's maintenance mode data file
            $downFile = storage_path('framework/down');

            // Ensure the maintenance file exists
            if (file_exists($downFile)) {
                // Decode the contents of the down file to get the Laravel-generated secret
                $data = json_decode(file_get_contents($downFile), true);
                $laravelSecret = $data['secret'] ?? null;

                // If the header token matches Laravel's maintenance secret, allow the request
                if ($headerSecret === $laravelSecret) {
                    // Create a valid cookie value (signed)
                    $cookie = MaintenanceModeBypassCookie::create($headerSecret);

                    // Inject directly into the request
                    $request->cookies->set('laravel_maintenance', $cookie->getValue());

                    return $next($request);
                }
            }

            // For normal browsing, pass through to the next middleware
            // Let Laravel's PreventRequestsDuringMaintenance handle the maintenance display
            return $next($request);

            // If maintenance file doesn't exist but app reports maintenance mode
            throw new HttpException(503, 'Service Unavailable');
        }

        // If not in maintenance mode, continue as usual
        return $next($request);
    }
}

中间件注册:app/Http/Kernel.php

我在全局中间件数组中注册了这个中间件,位置在PreventRequestsDuringMaintenance之前:

[...]
protected $middleware = [
    [...]
    \App\Http\Middleware\HeaderBypassForMaintenance::class,
    \Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
    [...]
];
[...]

在11.44.2中,这个逻辑完全没问题:当服务处于维护模式时,只要请求头携带正确的密钥,就能正常访问;但升级到11.45.0后,这个中间件似乎完全没被触发,请求直接被维护模式页面拦截。我检查了中间件的注册顺序,和之前版本完全一致,也确认了维护模式的配置文件存在且密钥正确。

想问下有没有人遇到类似问题?或者Laravel 11.45.0在维护模式的中间件执行逻辑上有什么变动我没注意到?我是不是漏掉了什么配置步骤?

内容来源于stack exchange

火山引擎 最新活动