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

Google PHP Client刷新Access Token后出现401未认证错误求助

Google Calendar API 刷新Access Token后401未认证问题排查与解决

初始Access Token调用Google Calendar API正常,但通过Refresh Token刷新后,新的Access Token调用API时抛出UNAUTHENTICATED(401)错误,以下是问题分析和解决方案:

问题1:刷新Token时的变量逻辑错误

在刷新Token的代码中,判断refresh_token存在的条件写错了变量:

// 错误代码
if (isset($accessToken['refresh_token'])) {
    $refreshToken = $newTokens['refresh_token'];
    $newToken['refresh_token'] = $refreshToken;
}

这里$accessToken是字符串类型的新access token,并非数组,导致该判断永远不成立,最终保存的$newToken缺失refresh_token字段,后续客户端无法完成有效认证。

问题2:核心调用代码的Token设置方式混乱

核心代码中同时调用setAccessToken和refreshToken,导致客户端Token状态冲突:

$client->setAccessToken('ya20.xxxxxx');
$client->refreshToken('1//xxxxxxx');

Google Client需要完整的Token数组(包含access_token、refresh_token、expires_at等字段)来自动管理认证周期,单独设置单个Token值会导致客户端无法正确验证Token有效性或触发自动刷新。

问题3:未完整保存Token返回结果

刷新Token后仅提取access_token,丢失了expires_in、token_type等关键字段,客户端无法判断Token是否过期,也无法正确发起刷新请求。


正确的Token刷新与使用流程

  1. 修正Token刷新代码,完整保存Token数组
$client = new GoogleClient();
$client->setClientId('XXXXXX');
$client->setClientSecret('XXXXX');
// 传入旧的完整Token数组(需包含refresh_token),而非单个access_token
$client->setAccessToken($oldTokenArray);

// 客户端会自动从旧Token数组中读取refresh_token完成刷新,无需手动传入
$newTokens = $client->fetchAccessTokenWithRefreshToken();

// 直接保存完整的newTokens数组(包含所有认证必要字段)
if (!empty($newTokens)) {
    // 将$newTokens存入数据库或缓存,供后续调用使用
    saveTokenToStorage($newTokens);
}
  1. 修正核心调用代码,使用完整Token数组
// 从存储中取出完整的Token数组
$savedToken = getTokenFromStorage();

$client = new GoogleClient();
$client->setClientId('XXXXXX');
$client->setClientSecret('XXXXX');
// 设置完整的Token数组
$client->setAccessToken($savedToken);

// 客户端自动检查Token是否过期,过期则自动刷新
if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken();
    // 刷新后更新存储中的Token
    updateTokenInStorage($client->getAccessToken());
}

$calendarId = 'primary';
$optParams = [
    'maxResults' => 10,
    'orderBy' => 'startTime',
    'singleEvents' => true,
    'timeMin' => date('c'),
];

$calendarService = new Calendar($client);
$results = $calendarService->events->listEvents($calendarId, $optParams);
  1. 确认Socialite授权配置
    你的Socialite代码已正确设置access_type=offline和prompt=consent select_account,确保用户首次授权时返回了refresh_token,这是后续刷新Token的前提,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:05:20