Laravel中间件无需继承特定基类,只需实现handle方法并正确注册;必须声明Closure $next参数,调用并返回$next($request)以放行;Auth::user()为null常因中间件位置过早;权限控制应分层,粗筛用中间件,细粒度用Policy或Gate。

中间件类必须继承 Illuminate\Http\Middleware\TrustProxies?错,该继承 Illuminate\Routing\Middleware\SubstituteBindings?也不对
Laravel 中间件不是靠继承某个特定基类来生效的,只要实现 handle 方法并正确注册,就是合法中间件。常见错误是照抄文档片段却漏掉 use Closure,导致 PHP 报 Too few arguments to function。
实操建议:
- 新建中间件用
php artisan make:middleware CheckRole,它会自动生成带Closure类型提示的标准签名 - 手写时务必声明第二个参数为
Closure $next,否则 Laravel 路由调度器无法传递请求链 - 不要在
handle里直接return response()后就结束——漏掉$next($request)会导致后续中间件和控制器完全不执行 - 如果需要提前终止,返回响应即可;如需放行,必须调用并返回
$next($request)
Auth::user() 在中间件里返回 null?检查请求生命周期阶段
中间件执行时用户认证可能尚未完成,尤其是放在 web 中间件组「之前」的位置(比如加在 kernel.php 的全局中间件列表顶部)。这时 Auth::user() 必然为 null,不是代码写错了,而是时机不对。
实操建议:
- 身份校验类中间件(如权限判断)应放在
auth和bindings之后,推荐塞进app/Http/Kernel.php的$middlewareGroups['web']数组中靠后位置 - 若必须在认证前运行,改用
Auth::guard('web')->user()并确认 guard 配置加载无误,但更稳妥的做法是依赖auth中间件先行触发登录态解析 - 调试时可在中间件开头加
Log::debug('User: ' . (Auth::check() ? Auth::id() : 'guest')),快速定位是否已过认证环节
用 @can Blade 指令做权限控制?别在中间件里重复造轮子
中间件适合做「请求准入」(例如禁止非管理员访问 /admin/*),而细粒度操作权限(如“编辑按钮是否显示”)应该交给 Blade 或 Policy,混用会导致逻辑分散、难以维护。
实操建议:
- 中间件只做粗筛:检查角色字段(
$user->role === 'admin')或核心权限位($user->hasPermissionTo('manage_users')),别在这里查数据库判断「当前用户能否编辑这篇帖子」 - 涉及模型实例的权限判断,统一走 Laravel 的
Gate::allows('update', $post)或$user->can('update', $post),并在对应 Policy 类中定义规则 - 如果中间件里频繁出现
Post::find()或DB::table()->where(),说明职责越界了——把数据查询和业务规则判断挪到 Controller 或 Policy 里
abort(403) 和 throw new AuthorizationException 效果一样?不完全是
两者都会返回 403 响应,但触发路径不同:abort(403) 是硬中断,绕过所有异常处理流程;而 AuthorizationException 会被 Laravel 的异常处理器捕获,并自动渲染成 403.blade.php 视图(如果存在),且支持在 App\Exceptions\Handler 中定制响应格式。
实操建议:
- 在中间件中推荐用
throw new AuthorizationException,尤其当项目已自定义 403 页面或需统一记录拒绝日志时 - 若中间件属于 API 路由,且期望返回 JSON 格式错误(
{"message": "Forbidden"}),则保持用abort(403)更直接,避免被视图渲染逻辑干扰 - 注意
AuthorizationException不会自动触发Auth::logout(),需要手动处理登出逻辑(比如权限失效时强制退出)
权限中间件真正难的不是写法,而是决定「在哪一层拦」——路由层?控制器方法前?还是模型操作时?同一套权限规则在不同层级混用,很快就会出现判断逻辑打架。留个心眼:先画清楚请求流经哪些关卡,再决定把哪条规则钉死在哪一环。


















