Laravel Breeze搭配Sanctum实现Token登出测试失败该如何解决
问题解答
1. Sanctum与Breeze兼容性说明
Sanctum完全可以正常搭配Breeze使用,官方推出的Breeze API版本默认就是基于Sanctum实现Token认证的,你的技术选型没有问题。
2. 测试失败的原因
你当前测试不通过主要有两个核心问题:
Sanctum::actingAs()是Laravel提供的测试专用模拟身份验证方法,不会真实生成持久化的Token,也不会走实际的Token校验逻辑,仅用于模拟用户身份快速测试其他接口逻辑。assertGuest()断言默认校验的是web session guard的登录状态,而你使用的是Sanctum API guard,二者并不互通,自然无法得到正确的断言结果。
3. 正确的登出功能测试实现
要验证登出后Token失效,需要模拟真实的Token调用逻辑,测试用例修改如下:
public function test_users_can_logout() { // 真实创建用户并生成有效Token $user = \App\Models\User::factory()->create(); $validToken = $user->createToken('MyAuthApp')->plainTextToken; // 携带有效Token请求登出接口 $response = $this->withHeader('Authorization', 'Bearer ' . $validToken) ->postJson('/api/logout'); // 断言登出接口调用成功 $response->assertOk() ->assertJson(['message' => 'log out successfully']); // 验证原Token已失效:携带该Token请求任意需要认证的接口,预期返回401 $this->withHeader('Authorization', 'Bearer ' . $validToken) ->getJson('/api/user') // 替换为你项目中任意需要认证的API路由即可 ->assertUnauthorized(); // 可选补充:验证数据库中该用户的所有Token已被删除 $this->assertDatabaseCount('personal_access_tokens', 0); }
4. 可选优化建议
如果你的项目是纯API项目,不需要web端session认证,可以修改config/auth.php配置,将api guard的驱动指定为sanctum,更贴合你的使用场景:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'sanctum', 'provider' => 'users', 'hash' => false, ], ],
你也可以修改测试基类的signIn方法,适配API测试场景:
protected function signIn($user = null) { $user = $user ?: \App\Models\User::factory()->create(); $token = $user->createToken('test-token')->plainTextToken; return compact('user', 'token'); }
后续其他API测试可以直接调用该方法拿到用户和有效Token,更贴近真实接口调用逻辑。
内容的提问来源于stack exchange,提问作者DeveloperX
相关产品推荐
相关产品推荐

