如何使用Laravel Passport测试API身份验证?遇401无效客户端问题
我明白你在Laravel Passport测试时遇到401「无效客户端」的痛苦——这问题我也踩过好几次,咱们一步步来排查解决:
1. 先确认客户端的类型是否正确
你在setUp里用了ClientRepository,但要注意:默认创建的客户端是授权码类型,而密码授权需要专门创建密码客户端。补全你的客户端创建代码:
$this->client = $clientRepository->createPasswordGrantClient( null, 'Test Password Client', 'http://localhost' // 测试用的回调地址,随便填就行 );
另外要确保测试环境下已经运行过Passport的迁移,oauth_clients表是存在的。
2. 正确生成访问令牌
创建用户和令牌的步骤要完整,这里给你两种常用方式:
方式一:模拟密码授权流程(和前端调用一致)
// 先创建测试用户 $this->user = User::factory()->create(); // 请求oauth/token接口获取令牌 $tokenResponse = $this->post('/oauth/token', [ 'grant_type' => 'password', 'client_id' => $this->client->id, 'client_secret' => $this->client->secret, 'username' => $this->user->email, 'password' => 'password', // 这里要和你的User Factory里的默认密码匹配 'scope' => '', ]); // 从响应里提取令牌 $this->token = $tokenResponse->json()['access_token'];
方式二:用Passport的测试快捷方法(生成个人访问令牌)
如果你的接口是用个人访问令牌验证,也可以这么写:
$this->user = User::factory()->create(); $this->token = $this->user->createToken('Test Token')->accessToken;
3. 测试请求必须正确携带令牌
调用受保护的接口时,一定要把令牌放到Authorization请求头里,格式是Bearer {token}:
$response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->get('/api/your-protected-endpoint'); // 断言接口返回成功 $response->assertStatus(200);
4. 排查数据库事务的影响
你用了DatabaseTransactions trait,它会在测试结束后回滚所有操作,但setUp里创建的客户端和用户在测试执行期间是有效的。不过如果还是有问题,可以临时去掉这个trait测试一下,看是不是事务导致的数据没有正确写入。
5. 检查Passport的基础配置是否到位
别漏掉这些基础步骤:
- 确保已经运行过
php artisan passport:install(测试环境也要执行,或者在测试的setUp里自动执行,但建议提前跑好) User模型已经引入HasApiTokenstrait:
use Laravel\Passport\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; }
config/auth.php里的api guard驱动设置为passport:
'guards' => [ 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
内容的提问来源于stack exchange,提问作者dddenis
相关产品推荐
相关产品推荐

