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

Laravel 9中Google Access Token刷新失败:refresh token缺失求助

解决Google Forms令牌无法刷新的问题

问题根源

你遇到的refresh token must be passed in or set as part of setAccessToken错误,核心原因是首次获取令牌时没有完整保存包含refresh_token的令牌数组,导致刷新时无法读取到有效的refresh_token;同时刷新代码存在逻辑错误,进一步加剧了问题。

修复步骤

1. 修正令牌获取代码

首先优化首次授权获取令牌的代码,确保保存完整的令牌数据(包含refresh_token):

$client = new \Google_Client();
// 移除废弃的setAuthConfigFile方法,仅保留setAuthConfig
$client->setAuthConfig(base_path().'/google-config.json');
$client->setRedirectUri('https://example.com/get-token');   
$client->addScope("https://www.googleapis.com/auth/forms.body");
$client->addScope("https://www.googleapis.com/auth/forms.responses.readonly");
$client->setAccessType('offline'); // 必须设置为offline才能获取refresh_token
$client->setApprovalPrompt('force');

if (! isset($_GET['code'])) 
{
    $auth_url = $client->createAuthUrl();
    return redirect(filter_var($auth_url, FILTER_SANITIZE_URL));
}
else 
{
    $client->authenticate($_GET['code']);
    // 获取完整的令牌数组(包含access_token、refresh_token等字段)
    $fullToken = $client->getAccessToken();
    // 将完整令牌写入文件,确保refresh_token被保存
    file_put_contents(storage_path('google_tokens.json'), json_encode($fullToken));
}

2. 修正令牌刷新代码

重新编写刷新逻辑,确保正确读取refresh_token并更新令牌:

$client = new \Google_Client();
$client->setAuthConfig(base_path().'/google-config.json');
$client->addScope("https://www.googleapis.com/auth/forms.body");
$client->addScope("https://www.googleapis.com/auth/forms.responses.readonly");

// 加载保存的完整令牌数据
$tokenPath = storage_path('google_tokens.json');
if (file_exists($tokenPath)) {
    $accessToken = json_decode(file_get_contents($tokenPath), true);
    $client->setAccessToken($accessToken);
}

// 检查令牌是否过期
if ($client->isAccessTokenExpired()) {
    // 获取保存的refresh_token
    $refreshToken = $client->getRefreshToken();
    
    // 如果refresh_token为空,说明之前未正确保存,需要重新引导用户授权
    if (!$refreshToken) {
        return redirect()->to('/get-token');
    }

    // 使用refresh_token获取新的access_token
    $newAccessToken = $client->fetchAccessTokenWithRefreshToken($refreshToken);
    
    // 合并原有refresh_token到新令牌数组(新响应不包含refresh_token)
    $newAccessToken['refresh_token'] = $refreshToken;
    
    // 更新客户端令牌
    $client->setAccessToken($newAccessToken);
    
    // 保存更新后的完整令牌
    file_put_contents($tokenPath, json_encode($newAccessToken));
}

关键注意事项

  • refresh_token仅首次授权返回:只有用户首次同意offline访问权限时,Google才会返回refresh_token,后续刷新令牌不会再返回该字段,因此必须在首次获取时完整保存。
  • 废弃方法移除:setAuthConfigFile是Google Client库的旧方法,已被setAuthConfig替代,无需重复调用。
  • 刷新后令牌合并:新获取的access_token不包含refresh_token,必须将原有refresh_token合并后再保存,否则下次刷新会再次失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:57:49