中间件必须调用 $next($request) 以确保请求链式传递;不调用会导致请求中断,后续中间件和控制器不执行;拦截需返回响应,全局中间件影响所有请求,路由中间件按需加载,顺序错误将导致逻辑异常。

中间件是 Laravel 请求处理管道里的“守门人”——它不直接干活,但决定请求能不能进、怎么进、带着什么进。
中间件 handle() 方法里为什么必须调用 $next($request)?
因为 Laravel 的中间件是链式执行的:每个中间件都得明确告诉框架“接下来交给谁”。handle() 方法不调用 $next($request),请求就卡死了,后面所有中间件和控制器都不会执行。
- 漏写
return $next($request)是新手最常踩的坑,现象是路由完全没响应(空白页或 500),日志里也看不到控制器日志 - 如果要做拦截(比如未登录跳转),必须 返回一个响应(如
redirect()->route('login')),而不是只写return或什么都不写 - 不能在
handle()里写exit或die,会绕过 Laravel 响应生命周期,导致事件、日志、异常处理全部失效
全局中间件 vs 路由中间件:什么时候该注册到 $middleware,什么时候用 $routeMiddleware?
区别不在功能强弱,而在「执行时机」和「作用范围」——选错会导致性能浪费或逻辑失控。
-
$middleware(在app/Http/Kernel.php)里的中间件对每一个 HTTP 请求都执行,包括静态资源、健康检查接口、甚至 OPTIONS 预检请求。别往里塞权限校验类逻辑 -
$routeMiddleware是按需加载的,只在你显式调用->middleware('auth')时才跑,适合做登录态检查、角色权限、API 签名验证等场景 - 跨域(CORS)、TrustProxies 这类影响底层通信的中间件,才适合放全局;而像
CheckAge、EnsureTokenIsValid这种业务相关中间件,一律走路由绑定
自定义中间件里怎么安全地读取请求参数或用户信息?
别在 handle() 开头就硬取 $request->user() 或 $request->input('id')——有些中间件执行时用户还没认证,或请求体还没被解析。
- 用户信息请用
$request->user(),但要先判断是否为 null;更稳妥的是依赖 Laravel 自带的auth中间件前置执行,再写你的业务中间件 - 读取 JSON 请求体?确保
App\Http\Middleware\TrimStrings和App\Http\Middleware\ConvertEmptyStringsToNull这类基础中间件已在管道靠前位置(它们负责解析请求体) - 想读 URL 参数或 Query 字符串,用
$request->query('key')更安全;$request->input()会合并 query + body + files,容易误判
中间件不是万能胶,它的威力恰恰来自克制:只做一件事,做好一件事。最容易被忽略的是中间件顺序——auth 必须在 role 前面,throttle 得在 cors 后面,顺序错了,逻辑就全乱了。










