Laravel 自定义中间件需手动注册到 app/Http/Kernel.php 的 $middlewareGroups 或 $routeMiddleware 中,路径须带完整命名空间;API 中间件应返回 response()->json() 并显式设状态码,禁用 redirect();不生效常见原因包括路由未归属 api 组、异常未捕获、环境配置差异;API 路由默认跳过 CSRF 验证,不应手动添加 VerifyCsrfToken。

怎么注册 Laravel 自定义中间件
中间件必须显式注册,否则 app/Http/Kernel.php 根本不会加载它。Laravel 不会自动扫描或发现中间件类。
实操建议:
- 在
app/Http/Kernel.php的$middlewareGroups(全局组)或$routeMiddleware(路由级)中添加键值对,例如:'auth.api' => \App\Http\Middleware\EnsureTokenIsValid::class - 别把中间件类路径写错——常见错误是漏掉
\App\Http\Middleware\命名空间前缀,导致报错Class "EnsureTokenIsValid" not found - 如果想用在 API 路由里,优先加到
$middlewareGroups['api'],而不是$routeMiddleware;后者更适合单个路由绑定,比如Route::get('/admin', ...)->middleware('admin.check')
中间件 handle() 方法里怎么终止请求并返回 JSON
Laravel 中间件默认返回 return $next($request) 表示放行,但 API 场景下常需提前中断并返回结构化错误响应,不能直接 die() 或 exit()。
实操建议:
- 用
response()->json()构造响应并return它,例如:return response()->json(['message' => 'Invalid token'], 401); - 别忘了在返回前调用
abort()或手动设状态码——response()->json(...)默认是 200,401、403 等需显式传第二个参数 - 避免在中间件里调用
redirect(),那是 Web 页面逻辑;API 中间件应始终返回 JSON 响应,否则前端收不到预期格式
为什么中间件不生效?检查这三处
最常踩的坑不是代码写错,而是注册或调用链断在了看不见的地方。
常见错误现象:
- 写了中间件、也注册了,但断点进不去
handle()—— 很可能是路由没走api组(比如用了Route::get而不是Route::middleware('api')->group(...)) - 中间件执行了,但
$next($request)后还是 500 —— 检查是否在中间件里抛了未捕获异常,Laravel 默认不格式化为 JSON,需要配合App\Exceptions\Handler::render()处理 - 本地测试 OK,部署后失效 —— 查
APP_ENV是否为production,某些中间件逻辑(如日志、调试头)可能被条件跳过
API 中间件要不要做 CSRF 验证
不要。Laravel 的 VerifyCsrfToken 中间件默认只对 web 中间件组启用,且明确排除了 api/* 路由前缀。
使用场景:
- 所有带
api前缀的路由(如Route::prefix('api')->group(...))都会被自动跳过 CSRF 检查 - 如果你手动把
VerifyCsrfToken加进了$middlewareGroups['api'],会导致所有 POST/PUT/PATCH 请求失败,报错TokenMismatchException - API 的身份校验靠 Token(如 Sanctum、Passport),不是 Cookie+CSRF,强行加反而破坏无状态设计
真正容易被忽略的是中间件的执行顺序:多个中间件串联时,前面的如果没 return $next($request),后面的就根本不会运行。写完务必用 php artisan route:list 确认中间件是否挂载到了目标路由上。










