jwt非法请求拦截需通过自定义中间件精准校验,注册到$routemiddleware并显式绑定路由,handle()中必须安全调用authenticate()且return响应,逐层验证签名、有效期、用户状态、角色权限及上下文绑定,并兜底处理cors与异常响应。

JWT 多用户非法请求拦截,关键不在“多用户”,而在“非法”——即请求携带了看似合法的 Token,但实际未授权、已过期、被篡改或不属于当前上下文。Laravel 本身不自动拦截这类请求,必须靠中间件在请求进入控制器前完成可信性校验。
中间件必须注册到 $routeMiddleware 并显式绑定路由
别把 JWT 校验中间件塞进 $middleware(全局)或 $middlewareGroups['api'](分组)里自动继承。原因很直接:
- 全局中间件会拦截
/health、静态资源、甚至队列触发的 HTTP 回调,导致运维通道失效 - API 分组自动应用的
auth:sanctum或throttle会与你自定义的 JWT 逻辑冲突,掩盖真实问题 - JWT 校验应精准作用于需要它的接口,比如
POST /api/v1/order,而不是所有 API
正确做法是:在 app/Http/Kernel.php 的 $routeMiddleware 中注册:
再在路由中显式调用:
Route::post('/order', [OrderController::class, 'store'])->middleware('jwt.verify');handle() 必须安全调用 authenticate() 并统一返回响应
JWT 中间件不是“验证完就完事”,它必须控制请求流向。常见错误是只写 JWTAuth::parseToken()->authenticate(); 却漏掉 return:
- ✅ 正确:
return $next($request);(认证通过,放行) - ✅ 正确:
return response()->json(['error' => 'Unauthorized'], 401);(失败时主动终止) - ❌ 错误:
JWTAuth::parseToken()->authenticate(); $next($request);(没 return,请求挂起) - ❌ 错误:
redirect('/login');(少 return,静默失败)
更稳妥的做法是在 try/catch 中包裹认证逻辑,捕获 TokenExpiredException、TokenInvalidException、UserNotDefinedException 等,并分别返回语义清晰的 401 响应。
非法请求的核心特征要逐层过滤,不能只看 Token 是否能解码
一个能被 JWT 库解析的 Token 不代表它合法。中间件需检查以下维度:
- 签名有效性:JWTAuth 自动校验,无需额外代码
- 有效期(exp/nbf):默认已校验,但可加日志记录过期时间用于审计
-
用户状态:调用
$user->isActive()或查数据库字段is_banned -
角色或权限匹配:如
!$user->hasRole('merchant')→ 返回 403 -
Token 绑定上下文:比对请求头
X-Device-ID是否与 Token 中自定义 claim 一致,防 token 复用
注意:$request->user() 只有在认证中间件执行后才可用。确保你的 VerifyJwtToken 在 auth:sanctum 之后运行,或干脆替代它——不要并存。
CORS 和异常响应必须兜底,否则前端看不到错误
JWT 认证失败时,中间件直接返回 401,但 Laravel 默认的 CORS 中间件可能尚未执行,导致响应缺失 Access-Control-Allow-Origin 头,浏览器直接屏蔽响应。
解决方式有两种:
- 在
app/Exceptions/Handler.php的render()方法中,对所有 JWT 相关异常响应手动添加头:response()->header('Access-Control-Allow-Origin', '*') - 新建一个轻量级全局中间件(放在
$middleware最前),对所有响应统一加 CORS 头,不依赖路由分组
避免依赖 .env 中的 CORS_ALLOWED_ORIGINS=*,那只是给预检请求(OPTIONS)用的,JWT 异常路径完全绕过它。











