You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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自带的权限校验方法,无需额外编写策略类:
    public function index()
    {
        if (!Voyager::can('browse_sendusermails')) {
            abort(403);
        }
        return view('logs.logs');
    }
    
    Voyager 1.4+版本可以直接在路由上挂载权限中间件,不需要在控制器内写校验逻辑:
    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
  • 清除缓存
    执行以下命令重置缓存:
    php artisan config:clear
    php artisan cache:clear
    php artisan permission:cache-reset
    

调整完成后重新登录admin账号访问对应路径即可正常通过权限校验。


内容的提问来源于stack exchange,提问作者Sławomir B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:36:19