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

Laravel Sanctum如何支持复合主键模型生成API令牌?

在复合主键的Laravel模型中使用Sanctum令牌的解决方案

Laravel Sanctum默认依赖模型的单一主键关联令牌,复合主键场景下会因getKey()返回数组导致array_key_exists报错,以下是适配复合主键的具体方案:

1. 扩展Sanctum令牌表

首先修改personal_access_tokens表,添加复合主键的第二个字段(这里是tenant_id)来存储完整的关联标识:

// 生成新迁移文件执行,或修改原有Sanctum迁移
Schema::table('personal_access_tokens', function (Blueprint $table) {
    $table->string('tenant_id')->nullable();
});

2. 修改PersonalAccessToken模型的关联逻辑

在app/Models/PersonalAccessToken.php中,重写tokenable关联方法,让它同时匹配tokenable_id和tenant_id:

public function tokenable()
{
    return $this->morphTo()->where('tenant_id', $this->tenant_id);
}

3. 自定义Device模型的令牌创建逻辑

在你的Device模型中,重写createToken和tokens关联方法,确保令牌创建时保存复合主键的两个字段,同时关联查询时匹配完整主键:

use Laravel\Sanctum\HasApiTokens;
use Laravel\Sanctum\PersonalAccessToken;
use Illuminate\Support\Str;

class Device extends Model
{
    use HasApiTokens;

    // 声明复合主键
    protected $primaryKey = ['device_id', 'tenant_id'];
    public $incrementing = false;

    /**
     * 重写令牌创建方法,保存tenant_id
     */
    public function createToken(string $name, array $abilities = ['*'])
    {
        $plainTextToken = Str::random(40);
        
        $token = $this->tokens()->create([
            'name' => $name,
            'token' => hash('sha256', $plainTextToken),
            'abilities' => $abilities,
            'tenant_id' => $this->tenant_id,
        ]);

        return new \Laravel\Sanctum\NewAccessToken($token, $token->getKey().'|'.$plainTextToken);
    }

    /**
     * 重写令牌关联,匹配复合主键
     */
    public function tokens()
    {
        return $this->morphMany(PersonalAccessToken::class, 'tokenable')
            ->where('tenant_id', $this->tenant_id);
    }
}

4. 验证功能

完成以上修改后,重新运行迁移,然后在控制器中调用$device->createToken('IoT Token')即可正常生成关联复合主键的Sanctum令牌,认证时Sanctum会通过tokenable_id和tenant_id共同匹配到对应的设备。

内容的提问来源于stack exchange,提问作者Ernesto Pareja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:20:47