Laravel Voyager为控制器分配自定义角色报403未授权问题
Laravel Voyager 自定义页面权限校验返回403解决方案
问题场景
在Laravel Voyager后台创建自定义页面时,参照官方文档完成以下配置:
- 在
permissions表创建权限键browse_sendusermails,并将该权限绑定到admin角色 - 路由定义代码:
Route::get('/sendusermails', [App\Http\Controllers\SendUserMailsController::class, 'index'])->middleware('admin.user');
- 控制器代码:
namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use TCG\Voyager\Facades\Voyager; class SendUserMailsController extends Controller { protected function guard() { return Auth::guard(app('VoyagerGuard')); } public function index() { $this->authorize('browse_sendusermails'); return view('logs.logs'); } }
访问路径http://127.0.0.1:8000/admin/sendusermails时持续返回403错误,提示This action is unauthorized.。将校验语句修改为$this->authorize('sendusermails');仍无法生效,删除权限校验代码后页面可正常加载。
问题根因
Voyager的权限体系和Laravel原生Gate授权做了适配,但直接在permissions表插入的自定义权限如果没有绑定对应模型策略,调用$this->authorize()时Laravel会因为找不到匹配的授权逻辑默认拒绝访问。此外当前路由定义没有放在admin前缀组下,会导致Guard识别异常,权限校验时拿不到当前登录admin用户的权限数据。
修复步骤
按以下顺序调整配置即可正常生效:
- 修正路由分组
将自定义路由放到Voyager的admin路由组下,自动继承前缀、中间件和Guard配置:Route::group(['prefix' => 'admin', 'middleware' => ['admin.user']], function () { Route::get('/sendusermails', [App\Http\Controllers\SendUserMailsController::class, 'index'])->name('voyager.sendusermails.index'); }); - 替换权限校验方式
不要直接调用Laravel原生的$this->authorize(),改用Voyager自带的权限校验方法,无需额外编写策略类:
Voyager 1.4+版本可以直接在路由上挂载权限中间件,不需要在控制器内写校验逻辑:public function index() { if (!Voyager::can('browse_sendusermails')) { abort(403); } return view('logs.logs'); }Route::get('/sendusermails', [App\Http\Controllers\SendUserMailsController::class, 'index']) ->middleware('admin.user', 'can:browse_sendusermails') ->name('voyager.sendusermails.index'); - 校验权限表数据
确认permissions表中新建的browse_sendusermails记录符合要求:- 非BREAD绑定的自定义页面,
table_name字段留空 key字段值严格为browse_sendusermails,大小写完全匹配permission_role关联表中存在对应记录,role_id匹配admin角色ID,permission_id匹配新建权限的ID
- 非BREAD绑定的自定义页面,
- 清除缓存
执行以下命令重置缓存:php artisan config:clear php artisan cache:clear php artisan permission:cache-reset
调整完成后重新登录admin账号访问对应路径即可正常通过权限校验。
内容的提问来源于stack exchange,提问作者Sławomir B
相关产品推荐
相关产品推荐

