Laravel 11 中间件优先级由 $middlewarePriority 数组显式控制,用于确保有状态中间件(如 session、auth、csrf)执行顺序正确;自定义中间件需插入该数组指定位置,路由中 middleware() 数组顺序无效,实际以 $routeMiddleware 定义顺序为准。

在 Laravel 11 中,给中间件设置执行优先级主要靠 显式声明中间件在 $middlewarePriority 数组中的位置,而不是靠路由里写的顺序或数组下标。这个机制专门用于协调「有状态中间件」(如 session、auth、csrf)之间的相对顺序,确保关键逻辑按预期先后触发。
必须用 $middlewarePriority 控制 auth 类中间件的前后关系
Laravel 11 默认已定义 $middlewarePriority 数组,它决定了部分核心中间件的强制执行次序。如果你的自定义中间件需要比 Authenticate 更早运行(比如子域名校验、租户识别),就必须把它加进这个数组,并放在 Authenticate::class 之前:
- 打开
app/Http/Kernel.php - 找到
protected $middlewarePriority = [...] - 把你的中间件类(带完整命名空间)插入到
Authenticate::class上方
例如,要让 Website 中间件一定先于认证执行:
protected $middlewarePriority = [
\App\Http\Middleware\Website::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Auth\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
];
路由级中间件顺序由 $routeMiddleware 声明位置决定
你通过 Route::middleware(['foo', 'bar']) 写的数组顺序不生效。真正起作用的是它们在 $routeMiddleware 数组里的定义顺序:
- 在
app/Http/Kernel.php的$routeMiddleware中,把依赖登录态的中间件(如ensure-profile)写在'auth' => ...行之后 - 把前置校验类(如
check-tenant)写在'auth'行之前 - 哪怕路由里写成
->middleware(['auth', 'check-tenant']),只要check-tenant在数组里排在前面,它就会先执行
全局和分组中间件按数组从上到下入栈
$middleware(全部请求)和 $middlewareGroups['web'](如 web 组)里的顺序是严格入栈顺序:
- 数组顶部的中间件最先执行(请求进入时)、最后响应(响应返回时)
- 比如
TrustProxies必须在最上面,否则后续中间件拿到的 IP 就不对 - 若你在
web组里把StartSession放在EncryptCookies后面,session 就无法解密 cookie
验证执行顺序最可靠的方式是打日志或 dd()
别猜,直接看:
- 在每个中间件
handle()开头加Log::info('running: '.class_basename($this)); - 或临时用
dd(class_basename($this), $request->path()); - 访问一个带多层中间件的路由,观察输出顺序
- 注意:不要在
terminate()里调试,它不参与主请求流











