Laravel 8访问/softwares路由遇403未授权错误求排查
Laravel 8 403权限问题排查与CRUD权限实现
一、核心问题排查步骤
1. 检查CheckPermission中间件逻辑
确保中间件正确从用户关联的角色中获取权限集合,而非仅查询用户直接绑定的权限(适配角色分配权限的架构):
// 错误示例:仅校验用户直接权限(不符合角色权限架构) public function handle(Request $request, Closure $next, ...$permissions) { if (!$request->user()->hasAnyPermission($permissions)) { abort(403); } return $next($request); } // 正确示例:遍历用户所有角色的权限进行校验 public function handle(Request $request, Closure $next, ...$permissions) { $userPermissions = $request->user()->roles->flatMap(function ($role) { return $role->permissions->pluck('name'); })->unique(); foreach ($permissions as $permission) { if (!$userPermissions->contains($permission)) { abort(403); } } return $next($request); }
2. 验证模型关联与权限方法
确保User、Role、Permission模型的关联关系正确配置:
User模型
public function roles() { return $this->belongsToMany(Role::class, 'role_user'); } // 获取用户所有角色的权限集合 public function getAllPermissions() { return $this->roles->flatMap(function ($role) { return $role->permissions; })->unique(); } // 校验单个权限 public function hasPermission($permission) { return $this->getAllPermissions()->contains('name', $permission); } // 校验多个权限(满足任一即可) public function hasAnyPermission($permissions) { return $this->getAllPermissions()->pluck('name')->intersect($permissions)->isNotEmpty(); }
Role模型
public function permissions() { return $this->belongsToMany(Permission::class, 'permission_role'); }
Permission模型
public function roles() { return $this->belongsToMany(Role::class, 'permission_role'); }
3. 确认路由中间件顺序
必须保证auth中间件在checkPermission之前执行,否则中间件无法获取当前认证用户:
// routes/web.php // 单个路由示例 Route::get('/softwares', [SoftwaresController::class, 'index']) ->middleware(['auth', 'checkPermission:view:software']);
4. 检查权限名称一致性
核对数据库permissions表中name字段的值与中间件传入的权限名称完全一致(注意大小写、冒号、空格无差异)。
5. 清理深层缓存
执行以下命令清理配置、路由及应用缓存:
php artisan config:clear php artisan route:clear php artisan cache:clear
二、软件CRUD权限控制实现要点
- 权限命名规范:统一采用
动作:资源格式(如view:software、create:software),便于管理和校验。 - 中间件全局注册:在
app/Http/Kernel.php的$routeMiddleware中注册自定义中间件:
protected $routeMiddleware = [ // ... 'checkPermission' => \App\Http\Middleware\CheckPermission::class, ];
- 完整CRUD路由配置:
Route::middleware(['auth'])->prefix('softwares')->group(function () { Route::get('/', [SoftwaresController::class, 'index'])->middleware('checkPermission:view:software'); Route::get('/create', [SoftwaresController::class, 'create'])->middleware('checkPermission:create:software'); Route::post('/', [SoftwaresController::class, 'store'])->middleware('checkPermission:create:software'); Route::get('/{software}', [SoftwaresController::class, 'show'])->middleware('checkPermission:view:software'); Route::get('/{software}/edit', [SoftwaresController::class, 'edit'])->middleware('checkPermission:update:software'); Route::put('/{software}', [SoftwaresController::class, 'update'])->middleware('checkPermission:update:software'); Route::delete('/{software}', [SoftwaresController::class, 'destroy'])->middleware('checkPermission:delete:software'); });
- Controller层双重校验(可选):
public function index() { if (!auth()->user()->hasPermission('view:software')) { abort(403); } // 业务逻辑代码 }
内容的提问来源于stack exchange,提问作者KIM CHAN
相关产品推荐
相关产品推荐

