Google API Client PHP SDK v2.11调用isAccessTokenExpired报expires_in未定义错误
问题原因
- Google API Client PHP SDK v2.11 版本存在已知逻辑缺陷:
authenticate方法处理OAuth2令牌响应时,未对缺失expires_in字段的返回结果做兼容补全,也不会自动添加created时间戳字段,最终返回仅包含access_token的数组。 - 该场景通常出现在用户非首次授权(无需重新确认权限)、使用特殊权限scope申请授权、服务账号模拟用户授权等边缘场景下,Google OAuth2端点返回的响应本身不携带
expires_in字段。 - 底层报错根源是
isAccessTokenExpired方法未做字段存在性校验,直接读取数组的expires_in键触发PHP警告。
解决方案
你可以根据项目情况选择以下任意一种方案修复:
方案1:手动补全令牌字段(无需修改SDK/升级版本)
在获取到访问令牌后,手动补全缺失的必填字段,Google官方默认的普通访问令牌有效期为3600秒,示例代码如下:
// 步骤1:兑换令牌后补全字段 $client->authenticate($_GET['code']); $accessToken = $client->getAccessToken(); // 补全缺失字段 if (!isset($accessToken['expires_in'])) { $accessToken['expires_in'] = 3600; } if (!isset($accessToken['created'])) { $accessToken['created'] = time(); } $_SESSION['access_token'] = $accessToken; $_SESSION['refresh_token'] = $client->getRefreshToken();
方案2:升级SDK到修复版本
该缺陷已在v2.12.0及之后的SDK版本中修复,升级到最新稳定版即可从底层解决问题,升级命令:
composer require google/apiclient:"^2.15"
方案3:调用过期校验前增加兼容判断
如果不方便修改令牌存储逻辑,可以在校验过期前先判断字段是否存在,缺失时直接认定令牌过期:
$client->setAccessToken($_SESSION['access_token']); $token = $client->getAccessToken(); // 字段缺失直接走刷新逻辑 if (!isset($token['expires_in'], $token['created']) || $client->isAccessTokenExpired()) { $client->refreshToken($_SESSION['refresh_token']); $_SESSION['access_token'] = $client->getAccessToken(); }
注意事项
请确保初始化SDK时已配置$client->setAccessType('offline'),且首次授权时已正确获取并存储refresh_token,避免刷新令牌时出现异常。
内容的提问来源于stack exchange,提问作者Bruno Leveque
相关产品推荐
相关产品推荐

