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

Laravel 10 Lumen生成JWT令牌报错:relatedTo参数为null

解决Lumen 10中JWT生成令牌报错:relatedTo(): Argument #1 ($subject) must be of type string, null given

错误原因

这个报错的核心是JWT令牌生成时需要的用户唯一标识(subject)为null,而Lcobucci\JWT要求该值必须是字符串类型。这个标识来自你模型中getJWTIdentifier()方法的返回值,也就是$this->getKey()——Laravel模型默认返回主键字段的值,如果你的模型没有正确指定主键,或者查询到的用户主键字段为空,就会返回null触发错误。

解决方案

1. 检查并设置模型主键

如果你的Auth.AppUser表的主键不是默认的id字段(比如是UserId、user_id等),必须在AppUser模型中显式指定主键:

use Tymon\JWTAuth\Contracts\JWTSubject;

class AppUser extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject
{
    use Authenticatable, Authorizable, HasFactory;

    protected $table = 'Auth.AppUser';
    // 新增:指定表的主键字段
    protected $primaryKey = '你的主键字段名'; 
    // 如果主键不是自增整数,还需要添加以下配置:
    // public $incrementing = false;
    // protected $keyType = 'string';

    protected $fillable = [
        'Username', 'Email','Phone','FullName','role',
    ];

    protected $hidden = [
        'password',
    ];

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }
}

2. 验证用户实例的主键值

在登录控制器中,查询到用户后先验证主键是否存在:

$user = AppUser::where('username', $request->username)->first();
if($user)
{
    // 新增:检查主键是否为空
    if(is_null($user->getKey())) {
        return response()->json([
            'metadata' => [
                'message' => '用户主键缺失',
                'code'    => 500
            ]
        ], 500);
    }
    
    // 注意:这里密码验证不应该用Crypt::decrypt,正确做法是用Hash::check
    if(Hash::check($request->password, $user->password))
    {
        $token = \Auth::login($user);
        $resp = [
            'response' => [
                'token'=> $token  
            ],
            'metadata' => [
                'message' => 'OK',
                'code'    => 200
            ]
        ];

        return response()->json($resp);
    }else{
        // 现有密码错误逻辑
        $resp = [
            'metadata' => [
                'message' => 'Username or Password Not Correct',
                'code'    => 401
            ]
        ];

        return response()->json($resp, 401);
    }
}

// 现有用户不存在逻辑
$resp = [
    'metadata' => [
        'message' => 'Username Atau Password Tidak Sesuai',
        'code'    => 401
    ]
];

return response()->json($resp, 401);

3. 修复密码验证逻辑(重要优化)

你当前使用Crypt::decrypt($user->password)来验证密码是错误的:

  • Crypt::decrypt用于解密对称加密的内容,而Laravel推荐用Hash::make()对密码进行哈希存储,这种哈希是不可逆的,验证时必须用Hash::check()。
  • 如果你之前是用Crypt::encrypt存储的密码,虽然可以用Crypt::decrypt,但这种方式安全性远低于哈希,建议改为哈希存储。

额外检查

  • 确认php artisan jwt:secret生成的密钥已经正确写入.env文件(JWT_SECRET=xxx)。
  • 确保bootstrap/app.php中已经正确启用了JWT服务和配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:47:30