Laravel 11 中间件组不再定义在 Kernel.php,而是必须在 bootstrap/app.php 的 withMiddleware() 中显式声明 web、api 等组;未声明则路由调用 middleware('api') 直接报错“Middleware group [api] does not exist”,且组内不包含认证逻辑,需手动叠加 auth:api 等中间件。

在 Laravel 11 中,中间件组(middleware group)本身是静态定义在 app/Http/Kernel.php 的 $middlewareGroups 数组里的,**不能直接在运行时动态“追加”或“前置”中间件到已注册的组中**。但你可以通过几种明确、推荐的方式实现等效效果:修改注册逻辑、复用现有组、或在路由定义时灵活组合。
修改 Kernel.php 中的中间件组定义
这是最直接、最清晰的做法。打开 app/Http/Kernel.php,找到 $middlewareGroups 数组,按需调整顺序或插入中间件:
- 要前置一个中间件(如
EnsureApiVersion),把它放在组数组的最前面 - 要追加一个中间件(如
LogRequestDuration),把它加在数组末尾
例如:
```php// app/Http/Kernel.php
protected $middlewareGroups = [
'api' => [
EnsureApiVersion::class, // ← 前置
EnsureTokenValid::class,
ThrottleRequests::class,
LogRequestDuration::class, // ← 追加
],
];
```
在路由定义中覆盖或扩展中间件组
使用 Route::middleware() 可以显式指定中间件列表,它会完全替代组默认配置——因此可用来“前置+继承+追加”:
- 先写你要前置的中间件
- 再用
...MiddlewareGroup::class展开原组(需手动复制或封装) - 最后追加新中间件
更实用的做法是:提取常用组合为常量或方法,避免硬编码重复。例如:
// 在 Kernel.php 或专用类中定义
public static $extendedApiMiddleware = [
EnsureApiVersion::class,
...self::$middlewareGroups['api'],
LogRequestDuration::class,
];
```
然后在路由中使用:Route::middleware(Kernel::$extendedApiMiddleware)->group(...)
利用中间件别名 + 动态组合(推荐用于条件化场景)
如果需要根据环境、请求参数等动态决定是否前置/追加,不建议改组定义,而应:
- 为自定义中间件注册别名(在
$middleware或$middlewareGroups中) - 在控制器构造函数或中间件自身内做判断,调用
$next($request)前后插入逻辑(即“逻辑前置/后置”,非注册顺序) - 或使用闭包中间件临时注入:
->middleware(function ($request, $next) { /* 前置逻辑 */ return $next($request); })
注意中间件执行顺序与层级关系
Laravel 中间件严格按数组顺序执行:索引靠前的先执行(进入时),靠后的后执行(退出时)。所以:
- “前置” = 数组索引最小,最早拦截请求
- “追加” = 数组索引最大,最晚处理响应(或最晚拦截请求)
- 路由级中间件 > 组级中间件 > 全局中间件(按注册位置分层)
务必测试实际执行顺序,尤其当多个中间件修改同一请求属性(如 $request->attributes)时。











