如何正确创建Laravel中间件以校验授权用户ID与数据库user_id匹配
你编写的中间件存在3个可直接导致逻辑失效的问题
- 查询没有实际执行:
Pass::where('user_id', $user)仅创建了数据库查询构造器对象,没有调用查询方法拉取结果,此时$editor是查询构造器实例,和整数类型的用户ID做相等判断永远返回false,永远无法通过权限校验。 - 空值访问风险:直接用
Auth::user()->id取用户ID时,如果路由没有提前挂载身份校验中间件,未登录状态下Auth::user()会返回null,直接访问id属性会触发运行报错。 - 校验逻辑错位:你的需求是确认当前登录用户在Pass表中存在匹配user_id的记录,而现有代码是拿用户ID和查询构造器做相等比较,完全偏离了校验目标。
修正后的中间件实现
<?php namespace App\Http\Middleware; use App\Models\Pass; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CanEdit { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // 前置校验登录状态,规避空值报错 if (!Auth::check()) { return redirect('home')->with('error', '请先完成登录'); } $currentUserId = Auth::id(); // 执行查询判断是否存在匹配的user_id记录,用exists()可减少查询开销 $isMatchedUser = Pass::where('user_id', $currentUserId)->exists(); if (!$isMatchedUser) { return redirect('home')->with('error', '您没有该操作的访问权限'); } return $next($request); } }
配套注意事项
- 完成中间件编写后,需要在
app/Http/Kernel.php中为该中间件注册路由别名,例如在$routeMiddleware数组中添加'can.edit' => \App\Http\Middleware\CanEdit::class,后续才能在路由定义中直接通过别名引用该中间件。 - 如果你的实际校验场景是“仅允许Pass记录的所属人编辑对应内容”(而非只要用户在Pass表有任意记录就放行),可以在中间件中直接读取路由绑定的Pass实例做所属权比对,参考代码:
// 从路由参数中获取绑定的Pass模型 $targetPass = $request->route('pass'); // 比对所属人ID if ($targetPass->user_id !== Auth::id()) { return redirect('home')->with('error', '无权操作他人发布的内容'); }
内容的提问来源于stack exchange,提问作者Drummer
相关产品推荐
相关产品推荐

