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刷新与使用流程
- 修正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); }
- 修正核心调用代码,使用完整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);
- 确认Socialite授权配置
你的Socialite代码已正确设置access_type=offline和prompt=consent select_account,确保用户首次授权时返回了refresh_token,这是后续刷新Token的前提,无需修改。
内容的提问来源于stack exchange,提问作者Siddhartha Choubey
相关产品推荐
相关产品推荐

