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

Laravel中Spatie权限库预加载角色关联用户报错排查

解决Spatie Laravel-Permissions在Sanctum中间件下预加载角色关联用户的报错问题

出现Class name must be a valid object or a string错误的核心原因是:在auth:sanctum中间件下,当前请求的认证guard为sanctum,而数据库中角色的guard_name默认是web,Spatie权限库的关联逻辑会自动匹配当前guard对应的用户模型,导致模型类名解析失败。以下是几种可行的解决方案:

方案1:重写Role模型的users关联,解除guard限制

如果你的web和sanctum guard使用同一个User模型,直接重写Role的关联方法,跳过guard自动匹配逻辑:

// app/Models/Role.php
namespace App\Models;

use Spatie\Permission\Models\Role as BaseRole;

class Role extends BaseRole
{
    public function users()
    {
        $userModel = config('auth.providers.users.model');
        
        return $this->belongsToMany(
            $userModel,
            config('permission.table_names.model_has_roles'),
            'role_id',
            'model_id'
        );
    }
}

之后在代码中使用自定义的Role模型:

use App\Models\Role;

Role::with('users')->get();

方案2:查询时指定关联的guard_name

如果只需要关联web guard下的用户,在预加载时过滤关联表的guard_name字段:

use Spatie\Permission\Models\Role;

Role::with(['users' => function ($query) {
    $query->wherePivot('guard_name', 'web');
}])->get();

方案3:为角色添加多guard支持

如果需要角色同时适配web和sanctum guard,创建角色时指定多个guard名称:

// 代码创建角色
Role::create([
    'name' => 'admin',
    'guard_name' => ['web', 'sanctum'],
]);

或者通过Artisan命令创建:

php artisan permission:create-role admin web,sanctum

这样角色会关联所有指定guard下的用户,在Sanctum中间件环境下也能正常加载关联数据。


内容的提问来源于stack exchange,提问作者Salim Djerbouh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:45:17