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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:06:24