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

Laravel使用Spatie Permission报错:web守卫无名为create的权限

问题原因

运行Seeder抛出该错误的核心诱因是权限分配逻辑的传参错误:

  • 你调用$role->givePermissionTo($permissions)时,传入的是自定义的权限配置二维数组,Spatie Permissions扩展包的givePermissionTo方法仅支持传入「权限模型实例」「权限名称字符串」,或由这两类值组成的数组/集合,无法识别你传入的带display_name、key等自定义字段的原始配置结构。
  • 包内部匹配权限时,会误将配置数组内的字段值作为权限名检索,最终触发找不到名为create(即你配置里的display_name字段值)、guard为web的权限报错。
修复方案

调整权限创建、分配的逻辑即可,两种写法任选:

写法1:传入已创建的权限实例

创建权限时收集返回的模型实例,直接传入实例完成分配:

public function run()
{
    $user = User::create([
        'name' => 'admin',
        'email' => 'instructor@gmail.com',
        'email_verified_at' => now(),
        'password' => 'password',
        'remember_token' => Str::random(10),
        'type' =>  User::TYPE_INSTRUCTOR,
    ]);

    $permissions = [
        [
            'name' => 'methods_create',
            'display_name' => 'create',
            'key' => 'methods',
        ],
        [
            'name' => 'methods_update',
            'display_name' => 'update',
            'key' => 'methods',
        ],
        [
            'name' => 'methods_delete',
            'display_name' => 'delete',
            'key' => 'methods',
        ],
    ];

    $role = Role::create(['name'=>'Instructor']);
    $permissionModels = [];
    foreach($permissions as $permission){
        $permissionModels[] = Permission::create($permission);
    }
    // 传入权限实例集合分配
    $role->givePermissionTo($permissionModels);
    $user->assignRole($role);
}

写法2:传入权限名称数组

从配置数组中提取所有权限的name字段值,传入权限名数组完成分配:

public function run()
{
    $user = User::create([
        'name' => 'admin',
        'email' => 'instructor@gmail.com',
        'email_verified_at' => now(),
        'password' => 'password',
        'remember_token' => Str::random(10),
        'type' =>  User::TYPE_INSTRUCTOR,
    ]);

    $permissions = [
        [
            'name' => 'methods_create',
            'display_name' => 'create',
            'key' => 'methods',
        ],
        [
            'name' => 'methods_update',
            'display_name' => 'update',
            'key' => 'methods',
        ],
        [
            'name' => 'methods_delete',
            'display_name' => 'delete',
            'key' => 'methods',
        ],
    ];

    $role = Role::create(['name'=>'Instructor']);
    foreach($permissions as $permission){
        Permission::create($permission);
    }
    // 提取所有权限名传入
    $role->givePermissionTo(array_column($permissions, 'name'));
    $user->assignRole($role);
}
额外排查项

如果修改代码后仍报错,依次做以下检查:

  • 运行Seeder前先执行php artisan permission:cache-reset清除权限缓存,Spatie Permissions会缓存权限注册表,旧缓存会导致新创建的权限无法被识别。
  • 如果项目使用了多guard,创建Role、Permission时需要显式传入guard_name字段,确保和用户模型使用的guard一致。
  • 检查自定义扩展的Permission模型,确认$fillable属性包含你需要写入的display_name、key等自定义字段,避免自定义字段写入失败。

内容的提问来源于stack exchange,提问作者mohamed sahleya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:48:22