Laravel 8使用Passport登录未返回Bearer令牌如何解决
问题现象
在Postman测试登录接口时,登录成功后接口未返回预期的Bearer令牌字符串,而是返回了包含Token模型信息的JSON结构,返回内容如下:
{ "success": true, "message": "User login succesfully, Use token to authenticate.", "token": { "name": "passport_token", "abilities": [ "*" ], "tokenable_id": 1, "tokenable_type": "App\\Models\\User", "updated_at": "2022-07-04T08:52:22.000000Z", "created_at": "2022-07-04T08:52:22.000000Z", "id": 6 } }
当前登录接口的实现代码如下:
public function login(Request $request) { $input = $request->only(['email', 'password']); $validate_data = [ 'email' => 'required|email', 'password' => 'required|min:8', ]; $validator = Validator::make($input, $validate_data); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => 'Please see errors parameter for all errors.', 'errors' => $validator->errors() ]); } // authentication attempt if (auth()->attempt($input)) { $token = auth()->user()->createToken('passport_token')->accessToken; return response()->json([ 'success' => true, 'message' => 'User login succesfully, Use token to authenticate.', 'token' => $token ], 200); } else { return response()->json([ 'success' => false, 'message' => 'User authentication failed.' ], 401); } }
问题原因
出现该问题的核心原因是API认证驱动的属性取值错误:
- 从返回的token结构(包含
abilities、tokenable_id、tokenable_type字段)可以判断,当前项目默认使用的是Laravel Sanctum认证组件,而非Laravel Passport - Sanctum调用
createToken()方法后返回NewAccessToken实例,该实例有两个公共属性:accessToken:是存储在数据库中的PersonalAccessToken模型实例,也就是你当前返回的结构化对象,不能直接用作Bearer令牌plainTextToken:是生成的明文令牌字符串,也就是需要返回给前端、放在请求Authorization: Bearer {token}头中做鉴权的有效值
- 当前代码错误地读取了
accessToken属性,因此返回了模型对象而非预期的令牌字符串。
修复方案
方案1:适配现有Sanctum认证(推荐,无需调整现有组件配置)
直接修改token取值的代码行,将读取accessToken改为读取plainTextToken即可:
// 原代码 // $token = auth()->user()->createToken('passport_token')->accessToken; // 修改为 $token = auth()->user()->createToken('passport_token')->plainTextToken;
修改后接口将返回标准的Bearer令牌字符串,前端可直接使用。
注意:
plainTextToken仅在生成token的当次接口请求中可以获取,数据库中不会存储明文值,前端拿到后需要自行持久化保存。
方案2:如果业务设计为使用Passport认证
如果原本计划用Passport而非Sanctum,需要依次检查修正以下配置:
- 打开
config/auth.php,将API guard的driver值从sanctum改为passport - 确认User模型中引入的trait是
Laravel\Passport\HasApiTokens,而非Sanctum对应的Laravel\Sanctum\HasApiTokens - 确认已经执行过Passport初始化命令:
php artisan passport:install
配置完成后,原有代码中读取->accessToken的写法就可以正常返回Passport生成的Bearer令牌。
内容的提问来源于stack exchange,提问作者Lalat Putih
相关产品推荐
相关产品推荐

