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

socialiteproviders/laravelpassport的getAccessTokenResponse返回空响应求助

问题场景

我们基于socialiteproviders/laravelpassport实现OAuth2.0用户认证:

  • 授权跳转流程正常:调用Socialite::driver('laravelpassport')->scopes(['offline_access'])->redirect()->getTargetUrl()能正确获取code和state值
  • 但用code兑换用户信息时失败:执行Socialite::driver('laravelpassport')->stateless()->setHttpClient(new \GuzzleHttp\Client(['verify' => false]))->user()无法拿到用户详情,排查发现getAccessTokenResponse($code)返回空对象{}
  • CAS服务器日志显示已成功生成access_token,但上述函数接收的响应为空

相关核心代码:

public function getAccessTokenResponse($code)
{       
    $response = $this->getHttpClient()->post($this->getTokenUrl(), [
        RequestOptions::HEADERS => $this->getTokenHeaders($code),
        RequestOptions::FORM_PARAMS => $this->getTokenFields($code),
    ]);
    
    return json_decode($response->getBody(), true);
}

其中:

  • getTokenHeaders返回:return ['Accept' => 'application/json'];
  • getTokenFields返回:
[
    'grant_type' => 'authorization_code',
    'client_id' => $this->clientId,
    'client_secret' => $this->clientSecret,
    'code' => $code,
    'redirect_uri' => $this->redirectUrl,
]

CAS服务器日志片段:

Created access token TST-accesstokengenerated, now encoding it as base64
2025-04-09  INFO  OAuth access token response: access_token=encodedTST-accesstokengenerated&expires_in=6199

排查与解决方案

1. 响应格式不匹配(核心原因)

从CAS日志可见,服务器返回的是key=value的表单格式,但代码中请求头指定了Accept: application/json,若CAS不支持根据Accept头切换响应格式,依然返回表单数据,会导致json_decode解析空字符串得到空对象。

修复方法:修改getAccessTokenResponse方法,兼容表单格式解析:

public function getAccessTokenResponse($code)
{       
    $response = $this->getHttpClient()->post($this->getTokenUrl(), [
        RequestOptions::HEADERS => $this->getTokenHeaders($code),
        RequestOptions::FORM_PARAMS => $this->getTokenFields($code),
    ]);
    
    $body = $response->getBody()->getContents();
    // 判断是否为表单格式,是则解析为数组
    if (str_contains($body, '=')) {
        parse_str($body, $result);
        return $result;
    }
    
    return json_decode($body, true) ?: [];
}

2. 补充Guzzle配置,处理重定向与编码

部分CAS服务器会在返回token时触发重定向,默认Guzzle未开启自动重定向;或响应编码问题导致解析失败,可补充配置:

$client = new \GuzzleHttp\Client([
    'verify' => false,
    'allow_redirects' => true, // 开启自动重定向
    'decode_content' => true, // 自动解码响应内容
]);
Socialite::driver('laravelpassport')->stateless()->setHttpClient($client)->user();

3. 严格校验redirect_uri参数

确认redirect_uri与授权跳转时的地址完全一致(包括域名、路径、末尾斜杠等),CAS对该参数的校验通常是严格匹配的,参数不匹配会导致静默返回空响应。

4. 开启Guzzle调试日志抓包

添加日志配置查看完整请求/响应细节,定位问题:

$client = new \GuzzleHttp\Client([
    'verify' => false,
    'debug' => fopen(storage_path('logs/guzzle_oauth.log'), 'a'), // 写入调试日志
]);

执行请求后查看storage/logs/guzzle_oauth.log,可确认实际收到的响应内容。


内容的提问来源于stack exchange,提问作者SDLBeginner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:03:12