中间件不生效主因是请求未抵达,须按注册位置、调用方式、执行逻辑三环节排查:先查Kernel.php中全局/分组/路由级注册是否正确,再通过日志验证handle()是否触发,最后确认$next($request)是否被return及顺序是否合理。

自定义中间件不生效,核心问题往往不是代码写错了,而是请求根本没走到它那里。排查要从“有没有挂上”“有没有触发”“有没有放行”三个环节入手。
检查中间件是否被正确挂载
中间件必须显式注册到某个执行管道里才会运行:
- 全局中间件($middleware):放在
app/Http/Kernel.php的$middleware数组里,对所有请求生效。适合日志、CORS 等通用逻辑,但别把 auth 类中间件放这里,否则静态资源也会被拦 - 中间件组($middlewareGroups):比如
web或api组。你的路由必须属于该组——要么定义在routes/web.php(自动归属 web 组),要么显式调用Route::middleware('web') - 路由级中间件($routeMiddleware):只在你主动调用时才启用,例如
->middleware('check.admin')。写了类但没在路由里加这行,等于没注册
确认中间件是否实际执行
在 handle() 方法开头加一行日志:
Log::debug('CheckAdmin middleware hit', ['uri' => $request->getRequestUri()]);
访问对应路由后,去 storage/logs/laravel.log 查看。没有这条日志,说明中间件压根没被调用;有日志但没效果,问题出在内部逻辑(比如判断条件写反、漏了 return)。
验证 handle() 是否合规放行
Laravel 中间件是洋葱模型,$next($request) 必须被 return,否则请求会卡死:
- ❌ 错误写法:
$next($request);(没 return,控制器不会执行) - ✅ 正确放行:
return $next($request); - ✅ 提前终止:
return redirect('/login');或return response()->json(['error' => 'Forbidden'], 403);
任何拦截逻辑都必须有明确的 return,不能只写 redirect() 就结束函数。
留意顺序与依赖冲突
中间件顺序决定执行时机。比如:
- CORS 中间件如果放在
StartSession后面,session 启动失败可能导致它跳过 - 预检请求(OPTIONS)若被
auth:sanctum拦截,浏览器就收不到跨域头 - 运行
php artisan route:list --path=/your-route,确认输出中 Middlewares 列是否包含你的中间件名。缺失说明注册或调用有误;存在但无效,重点查它前后的中间件是否提前中断了流程











