Laravel 8中配合Auth::guard定义的Gates不生效返回403未授权问题
问题原因
- Gate 闭包的第一个参数默认是当前默认 guard 认证的用户实例,你在 Gate 定义外声明的
$admin = Auth::guard('admin');不会传入闭包,且只会在服务提供者启动时执行一次,无法获取每次请求的登录管理员信息。 - 你定义 Gate 时要求传入
AdminsRole $adminsroles参数,但路由中使用can:add-category中间件时没有传递对应参数,会直接导致 Gate 校验失败返回403。 - Gate 中不需要注入
AdminsRole实例,你使用的是静态查询,直接调用模型类的静态方法即可。
修复方案
- 修正
AuthServiceProvider.php中的 Gate 定义:
// 头部先导入需要的类 use App\Models\AdminsRole; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Gate; Gate::define('add-category', function () { // 每次校验时获取当前admin guard的登录用户 $adminUser = Auth::guard('admin')->user(); // 未登录直接拒绝 if (!$adminUser) { return false; } // 超管直接放行 if ($adminUser->u_type === 'superadmin') { return true; } // 直接用静态查询判断权限是否存在,exists比count性能更高 return AdminsRole::where([ ['admin_id', $adminUser->id], ['module', 'categories'], ['add_access', '1'], ])->exists(); });
- 控制器中多余的
AdminsRole注入可以移除(如果方法内没有用到该实例的话):
public function addcategory() { return view('add-category'); }
- 路由代码无需修改,保持原有配置即可。
额外排查点
如果修复后仍返回403,可逐一排查以下项:
- 确认
config/auth.php中adminguard 配置正确 - 确认当前登录的管理员账号,在
admins_roles表中存在module=categories且add_access=1的记录 - 可在Gate闭包中增加日志打印逻辑,输出查询参数和结果,排查数据匹配问题
内容的提问来源于stack exchange,提问作者TeDeveloper
相关产品推荐
相关产品推荐

