使用Laravel Passport的Client Credentials Grant Token,如何从带Bearer头的请求获取client id?
嘿,刚好有过类似的实践,Laravel Passport针对Client Credentials Grant场景,其实提供了挺便捷的方式来获取客户端ID,给你分享几个实用方案:
方法一:直接通过API守卫获取(最推荐)
只要你的路由已经应用了auth:api中间件,Passport在验证Bearer Token后,会自动把客户端实例绑定到API守卫上,直接调用就能拿到ID:
// 在控制器或路由闭包中 $clientId = auth()->guard('api')->client()->id;
注意:Client Credentials模式下,auth()->user()返回的是null(因为没有关联用户),但client()方法会返回对应的客户端模型实例,这是Passport专门为该授权模式提供的方法。
方法二:封装中间件复用(多场景适用)
如果项目里多个接口都需要获取客户端ID,可以封装一个中间件,把ID注入到请求实例中,避免重复代码:
- 先创建中间件:
php artisan make:middleware InjectClientId
- 编辑中间件的
handle方法:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class InjectClientId { public function handle(Request $request, Closure $next) { // 确保请求已经通过API认证 if ($client = auth()->guard('api')->client()) { // 将client_id绑定到请求属性,后续可直接获取 $request->attributes->set('client_id', $client->id); } return $next($request); } }
- 在
app/Http/Kernel.php中注册中间件:
protected $routeMiddleware = [ // ... 其他中间件 'inject.client_id' => \App\Http\Middleware\InjectClientId::class, ];
- 在需要的路由上使用(注意要放在
auth:api之后):
Route::get('/your-endpoint', function(Request $request) { $clientId = $request->attributes->get('client_id'); // 业务逻辑... })->middleware(['auth:api', 'inject.client_id']);
方法三:手动解析Token(应急方案)
如果因为特殊情况没法用守卫,也可以手动解析Bearer Token来获取client_id,但这种方式需要自己处理Token无效、不存在的情况,不如前两种优雅:
use Laravel\Passport\Token; // 从请求头中提取Token $bearerToken = $request->header('Authorization'); if (!$bearerToken || !str_starts_with($bearerToken, 'Bearer ')) { // 处理Token不存在的情况 abort(401, 'Invalid authorization header'); } $token = substr($bearerToken, 7); // 去掉"Bearer "前缀 $accessToken = Token::findToken($token); if (!$accessToken || $accessToken->revoked) { abort(401, 'Invalid token'); } $clientId = $accessToken->client_id;
额外注意事项
- 确保你的客户端是通过
client_credentials授权类型创建的,可以通过Passport的命令或者后台面板查看。 - 检查
config/auth.php中api守卫的驱动是否设置为passport:
'guards' => [ 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
内容的提问来源于stack exchange,提问作者bezz
相关产品推荐
相关产品推荐

