如何设置Laravel中间件实现全局应用?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1069个文字,预计阅读时间需要5分钟。
全局中间件会在每个HTTP请求中执行,无需手动在路由或控制器中重复绑定。核心操作是将中间件类名添加到数组中,该数组位于+$middleware+文件中的+app\Http\Kernel.php+文件的+$middleware+属性中。
常见错误是误加到 $middlewareGroups(比如 web 或 api)里,那样只对对应路由组生效,不是真正“全局”。
- 打开
app/Http/Kernel.php - 找到
protected $middleware = [];这一行 - 在数组中追加你的中间件类完整命名空间,例如:
\App\Http\Middleware\ForceHttps::class - 确保该中间件类已存在,且
handle()方法逻辑正确
Laravel 全局中间件的执行顺序很重要
中间件按数组顺序从上到下执行,越靠前的越早进入、越晚退出(类似洋葱模型)。如果顺序错乱,可能造成依赖未初始化、响应被提前终止等问题。
比如你写了日志中间件和权限校验中间件,但把权限校验放在最前面,而日志需要读取用户信息——此时用户还没被认证中间件赋值,auth()->user() 就是 null。
- 认证类中间件(如
\App\Http\Middleware\Authenticate::class)通常应放在会话、加密等基础中间件之后 - 日志、监控类中间件建议靠后,避免记录未完成的请求
- 修改请求体的中间件(如解析 JSON body)必须在框架默认的
TrimStrings或ConvertEmptyStringsToNull之前,否则原始数据已被处理
为什么有些中间件加了也不生效
最常见原因是中间件本身返回了 return $next($request) 以外的内容,或者抛出了异常但没被捕获,导致后续中间件和路由直接跳过。
另一个隐蔽问题是中间件构造函数中做了阻断性操作(如依赖注入失败、配置缺失),Laravel 在实例化阶段就报错,整个请求直接 500,连日志都看不到执行痕迹。
- 检查中间件
handle()方法是否漏掉return $next($request) - 运行
php artisan route:list确认中间件确实没被意外排除(比如某些包会覆盖 Kernel) - 用
dd()或日志写入,在handle()开头简单打点,确认是否真被调用 - 注意 Artisan 命令、队列任务、WebSocket 等非 HTTP 场景不走这个中间件栈
全局中间件 vs 路由组中间件怎么选
不是所有中间件都适合全局注册。比如 CSRF 验证只对 web 路由有意义,加到全局会导致 API 接口 419;同理,跨域中间件如果对所有请求都发 Access-Control-Allow-Origin,可能暴露内部服务。
性能上也要留意:全局中间件每次请求必跑,哪怕只是做一次时间戳记录,积少成多也会影响首字节时间(TTFB)。
- 身份认证、HTTPS 强制、请求 ID 注入这类基础设施型逻辑适合全局
- 业务相关逻辑(如租户识别、A/B 测试分流)优先走
Route::middleware()或中间件组 - 调试类中间件(如查询计数、内存占用)绝对不要放全局,尤其在线上环境
Request 对象上的某个属性,而那个属性是另一个中间件设置的——但两个中间件没在 $middleware 里按序排列,结果就是日志总为空。这种问题不会报错,只会静默失效。本文共计1069个文字,预计阅读时间需要5分钟。
全局中间件会在每个HTTP请求中执行,无需手动在路由或控制器中重复绑定。核心操作是将中间件类名添加到数组中,该数组位于+$middleware+文件中的+app\Http\Kernel.php+文件的+$middleware+属性中。
常见错误是误加到 $middlewareGroups(比如 web 或 api)里,那样只对对应路由组生效,不是真正“全局”。
- 打开
app/Http/Kernel.php - 找到
protected $middleware = [];这一行 - 在数组中追加你的中间件类完整命名空间,例如:
\App\Http\Middleware\ForceHttps::class - 确保该中间件类已存在,且
handle()方法逻辑正确
Laravel 全局中间件的执行顺序很重要
中间件按数组顺序从上到下执行,越靠前的越早进入、越晚退出(类似洋葱模型)。如果顺序错乱,可能造成依赖未初始化、响应被提前终止等问题。
比如你写了日志中间件和权限校验中间件,但把权限校验放在最前面,而日志需要读取用户信息——此时用户还没被认证中间件赋值,auth()->user() 就是 null。
- 认证类中间件(如
\App\Http\Middleware\Authenticate::class)通常应放在会话、加密等基础中间件之后 - 日志、监控类中间件建议靠后,避免记录未完成的请求
- 修改请求体的中间件(如解析 JSON body)必须在框架默认的
TrimStrings或ConvertEmptyStringsToNull之前,否则原始数据已被处理
为什么有些中间件加了也不生效
最常见原因是中间件本身返回了 return $next($request) 以外的内容,或者抛出了异常但没被捕获,导致后续中间件和路由直接跳过。
另一个隐蔽问题是中间件构造函数中做了阻断性操作(如依赖注入失败、配置缺失),Laravel 在实例化阶段就报错,整个请求直接 500,连日志都看不到执行痕迹。
- 检查中间件
handle()方法是否漏掉return $next($request) - 运行
php artisan route:list确认中间件确实没被意外排除(比如某些包会覆盖 Kernel) - 用
dd()或日志写入,在handle()开头简单打点,确认是否真被调用 - 注意 Artisan 命令、队列任务、WebSocket 等非 HTTP 场景不走这个中间件栈
全局中间件 vs 路由组中间件怎么选
不是所有中间件都适合全局注册。比如 CSRF 验证只对 web 路由有意义,加到全局会导致 API 接口 419;同理,跨域中间件如果对所有请求都发 Access-Control-Allow-Origin,可能暴露内部服务。
性能上也要留意:全局中间件每次请求必跑,哪怕只是做一次时间戳记录,积少成多也会影响首字节时间(TTFB)。
- 身份认证、HTTPS 强制、请求 ID 注入这类基础设施型逻辑适合全局
- 业务相关逻辑(如租户识别、A/B 测试分流)优先走
Route::middleware()或中间件组 - 调试类中间件(如查询计数、内存占用)绝对不要放全局,尤其在线上环境
Request 对象上的某个属性,而那个属性是另一个中间件设置的——但两个中间件没在 $middleware 里按序排列,结果就是日志总为空。这种问题不会报错,只会静默失效。
