中间件放行关键在handle方法显式return:返回$next($request)继续流程,返回响应则终止;常见错误是遗漏return或分支不全导致请求穿透。

中间件里怎么判断当前请求是否该放行
关键在 handle 方法的返回值:返回 $next($request) 就继续往下走,返回响应(比如 response()->json(...) 或重定向)就终止流程。
常见错误是忘了 return,或者条件分支里只写了 if 没写 else,结果非预期请求直接穿透到路由,看似“没生效”。
- 必须显式 return,哪怕只是
return $next($request) - 检查所有分支路径——比如 if 是登录态校验,else 分支不能漏掉
return response()->forbidden() - 调试时可在中间件开头加
Log::debug('middleware hit', ['url' => $request->fullUrl()]),确认它真被调用了
Laravel 自带的 auth 和 auth.basic 中间件区别在哪
auth 依赖 session + cookies,适合 Web 表单登录;auth.basic 基于 HTTP Basic Auth,无状态,适合 API 调试或简单服务端验证。
用错会导致 419 或 401 反复出现,尤其在 Postman 测 API 时误配 auth 中间件,却没带 session cookie。
-
auth:读session存储里的用户 ID,再查数据库,依赖StartSession中间件前置 -
auth.basic:从请求头Authorization: Basic xxx解码用户名密码,直连数据库比对,不依赖 session - API 场景优先选
auth:sanctum或auth:api(如果配了 token guard),别硬套auth.basic
自定义中间件里怎么安全获取和修改请求参数
别直接改 $request->all() 返回的数组——它是副本;要改原始请求数据,得用 $request->merge([...]) 或新建 Request 实例。
典型翻车点:想给请求加个 tenant_id,但只写了 $request->merge(['tenant_id' => 123]) 却没接住返回值,后续控制器还是拿不到。
-
$request = $request->merge(['tenant_id' => $id])才真正更新请求对象 - 敏感操作如过滤字段(如删掉
password_confirmation),建议用$request->except('password_confirmation')而不是手动 unset - 若需深度修改(如解密参数),考虑在中间件里 new 一个自定义
Request类并传入,避免污染原始请求
中间件顺序错了会出什么问题
顺序决定执行链:靠前的中间件看到的是“裸请求”,靠后的看到的是已被加工过的请求。比如 EncryptCookies 必须在 StartSession 前,否则 session 解不开。
最常踩的坑是把鉴权中间件(如 auth)放在日志中间件之后,结果日志里记录的用户 ID 总是 null——因为鉴权失败,根本没走到 $next(),日志中间件也就没机会读到用户信息。
- 查看当前全局中间件顺序:看
app/Http/Kernel.php的$middleware、$middlewareGroups、$routeMiddleware - 路由级中间件(
->middleware('auth'))总在全局中间件之后执行 - 调试时用
dd($request->user())在每个中间件里打点,看哪一步开始为 null
中间件链条像水管,堵在哪,后面的水就到不了。顺序不是随便排的,尤其是涉及 session、加密、鉴权这些有依赖关系的环节。









