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

Laravel测试与JWT认证异常:测试环境JWTAuth::attempt返回false

问题排查与解决方案

核心问题1:用户密码未哈希存储

你的测试用例中创建用户时直接存入明文密码'123456',但JWTAuth::attempt()方法会自动对请求中的密码进行哈希,再与数据库中的值比对。数据库里的明文密码和哈希后的密码不匹配,导致验证失败。

修复方法:创建用户时使用Hash::make()生成哈希密码:

$user = User::factory()->create([
    'name' => 'Dude',
    'email' => 'dude@mail.com',
    'password' => Hash::make('123456'), // 替换为哈希密码
    'google2fa_secret' => $google2faSecret,
    'email_verified_at' => now(),
]);

核心问题2:测试用例错误使用actingAs()

actingAs($user)会提前让用户通过Laravel的认证系统登录,但你的登录接口本身需要接收邮箱和密码进行验证。这个操作会导致接口中Auth::user()有值,但JWTAuth::attempt()仍会验证请求中的密码,同时不符合接口的实际调用场景。

修复方法:移除actingAs($user),直接发送登录请求:

$response = $this->json('POST', '/api/login', [
    'email' => $user->email,
    'password' => '123456', // 这里用明文密码,JWTAuth会自动哈希验证
]);

额外检查项

  • 确认.env.testing中的JWT_SECRET已正确配置,且PHPUnit测试时加载了该环境文件(Laravel默认会加载,若未生效可在phpunit.xml中添加<env name="APP_ENV" value="testing"/>)。
  • 确保User模型实现了Tymon\JWTAuth\Contracts\JWTSubject接口,并完成getJWTIdentifier()和getJWTCustomClaims()方法的编写(这是JWTAuth正常工作的基础要求)。

修复后的完整测试用例

use Illuminate\Support\Facades\Hash;

public function testLogin()
{
    $randomBytes = random_bytes(10);
    $google2faSecret = Base32::encodeUpper($randomBytes);

    $user = User::factory()->create([
        'name' => 'Dude',
        'email' => 'dude@mail.com',
        'password' => Hash::make('123456'),
        'google2fa_secret' => $google2faSecret,
        'email_verified_at' => now(),
    ]);

    $user->assignRole('vendor');

    $response = $this->json('POST', '/api/login', [
        'email' => $user->email,
        'password' => '123456',
    ]);

    $response->assertStatus(200);
    $response->assertJsonStructure(['token']); // 更严谨的断言方式
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:14:55