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

Laravel Passport中如何用UUID作为sub声明值(不改主键及迁移)

解决Laravel Passport JWT中用UUID替换主键作为sub声明的问题

要在不修改用户模型主键、不改动oauth_access_tokens和oauth_auth_codes表迁移的前提下,让Passport生成的JWT用users表的subject_id(UUID字段)作为sub声明,只需通过自定义AccessToken模型并替换默认实现即可,步骤如下:

1. 创建自定义AccessToken模型

新建App\Models\AccessToken类,实现AccessTokenInterface并继承Passport原生的AccessToken模型,重写与JWT声明相关的方法:

<?php

namespace App\Models;

use Laravel\Passport\AccessToken as PassportAccessToken;
use Laravel\Passport\Contracts\AccessTokenInterface;

class AccessToken extends PassportAccessToken implements AccessTokenInterface
{
    /**
     * 重写获取JWT subject的方法
     * 返回用户的UUID字段(subject_id)而非主键id
     */
    public function getSubject(): string
    {
        return $this->user->subject_id;
    }

    /**
     * 重写JWT生成逻辑(原Trait中为私有方法,无法直接复用)
     */
    public function convertToJWT(): string
    {
        return \Firebase\JWT\JWT::encode(
            $this->getJWTClaims(),
            $this->getPrivateKey(),
            'RS256'
        );
    }

    /**
     * 构建JWT的所有声明字段
     */
    protected function getJWTClaims(): array
    {
        return [
            'iss' => url('/'),
            'sub' => $this->getSubject(),
            'aud' => $this->getAudience(),
            'iat' => $this->getIssueTime(),
            'exp' => $this->getExpirationTime(),
            'jti' => $this->getJti(),
            'scopes' => $this->scopes(),
        ];
    }
}

2. 配置Passport使用自定义模型

在App\Providers\AuthServiceProvider的boot方法中,指定Passport使用我们的自定义AccessToken模型:

<?php

namespace App\Providers;

use App\Models\AccessToken;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        // 你的策略配置
    ];

    public function boot(): void
    {
        $this->registerPolicies();

        Passport::routes();
        
        // 替换为自定义AccessToken模型
        Passport::useAccessTokenModel(AccessToken::class);
    }
}

3. 确保User模型可访问subject_id字段

在App\Models\User中,确保subject_id字段在$fillable中(或未被$hidden隐藏,不影响关联访问即可):

protected $fillable = [
    'name', 'email', 'password', 'subject_id',
];

原理说明

  • 自定义模型实现了AccessTokenInterface,重写getSubject直接返回用户的UUID字段,替代原生的主键id
  • 由于原生AccessTokenTrait中生成JWT的方法为私有,我们重新实现了convertToJWT和getJWTClaims逻辑,确保JWT生成时使用新的sub值
  • 此方案不会改动Passport的底层关联逻辑:oauth_access_tokens表的user_id仍存储用户主键,令牌验证时Passport依然通过该字段关联用户,仅JWT的sub声明替换为UUID,避免暴露主键

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:05:22