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

tymondesigns/jwt-auth的attempt方法始终返回false问题求助

我来帮你排查这个JWTAuth::attempt()始终返回false的问题,结合你用bcrypt加密的场景,大概率是凭证匹配逻辑或者模型配置的问题,咱们一步步来解决:

1. 先搞懂attempt()的默认逻辑(关键!)

JWTAuth::attempt()方法默认是按照email和password这两个字段来验证的——它会先找对应email的用户,再用bcrypt比对password字段的哈希值。但你现在用的是mobile和code作为凭证,这就导致默认逻辑找不到匹配的字段,自然返回false。

解决这个问题有两种思路:

思路一:手动验证+生成令牌

跳过attempt(),自己完成用户查找和密码比对,再手动生成令牌,代码可以改成这样:

use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;

$credentials = $request->only('mobile', 'code');

// 第一步:通过mobile找到对应的用户
$user = \App\Models\User::where('mobile', $credentials['mobile'])->first();

// 第二步:验证用户存在,且code(密码)的哈希匹配
if (!$user || !Hash::check($credentials['code'], $user->password)) {
    return response()->json(['error' => 'invalid_credentials'], 401);
}

// 第三步:手动为用户生成JWT令牌
$token = JWTAuth::fromUser($user);

return response()->json(compact('token'));

思路二:重写用户模型的验证字段

如果你想继续用attempt()方法,可以在User模型里重写getAuthPassword()方法,同时指定登录字段:

// User模型文件
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Model implements JWTSubject
{
    // 必须实现的JWT接口方法
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

    // 重写这个方法,返回你存储bcrypt哈希的字段(比如你的password字段)
    public function getAuthPassword()
    {
        return $this->password; // 这里要和你数据库里存哈希的字段对应
    }
}

然后调用attempt()时,需要把code映射为password字段,让方法能识别:

// 在你的控制器里
$credentials = $request->only('mobile', 'code');

// 调整字段名,适配attempt()的默认逻辑
$credentials['password'] = $credentials['code'];
unset($credentials['code']);

try {
    if (! $token = JWTAuth::attempt($credentials)) {
        return response()->json(['error' => 'invalid_credentials'], 401);
    }
} catch (JWTException $e) {
    return response()->json(['error' => 'could_not_create_token'], 500);
}

return response()->json(compact('token'));
2. 确认哈希生成的正确性

一定要确保你在存储用户密码(code)的时候,是用bcrypt()或者Hash::make()加密的,比如创建用户时:

// 正确的加密方式
$user = new \App\Models\User();
$user->mobile = $request->mobile;
$user->password = bcrypt($request->code); // 或者 Hash::make($request->code)
$user->save();

如果存的时候是明文,或者用了其他加密方式,那Hash::check()肯定比对失败,attempt()也会返回false。

3. 检查用户模型的JWT接口实现

别忘了你的User模型必须实现Tymon\JWTAuth\Contracts\JWTSubject接口,也就是上面代码里的那两个方法——这是JWT扩展正常工作的前提,少了的话不仅attempt()会出问题,生成令牌也会失败。

4. 排除用户状态问题

如果你的用户表有类似status(是否启用)的字段,attempt()默认不会检查这个,所以如果用户被禁用了,也会返回false。这种情况可以在查找用户时加上状态判断:

$user = \App\Models\User::where('mobile', $credentials['mobile'])
            ->where('status', 1) // 假设1代表启用状态
            ->first();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:35:37