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

如何检查Google API access token是否过期?Node.js客户端自动刷新问题

问题原因说明
  • oauth2Client.getTokenInfo()本质是调用Google官方的令牌校验接口,过期的令牌调用该接口会直接返回400类错误,你之前遇到的抛错属于正常行为
  • 库自带的自动刷新机制触发需要两个前提:你已经将用户对应的refresh_token、上次获取的expiry_date(令牌过期时间戳)赋值给oauth2Client实例;你调用的是库封装的API请求方法,而非单独调用getTokenInfo方法,所以你的场景下不会触发自动刷新
  • 将tokens事件监听写在路由内部会导致每次请求都重复注册监听器,属于逻辑错误,自然不会有预期输出
本地判断令牌是否过期的实现方案

你完全不需要调用远程接口,只需要在用户首次授权拿到令牌时,将access_token、refresh_token、expiry_date三个字段和userId绑定存储在你的数据库中,后续本地计算即可得到是否过期的布尔值,不会产生任何报错。

工具函数实现

/**
 * 判断令牌是否过期
 * @param {number} expiryDate 令牌过期时间戳(登录获取令牌时返回的expiry_date字段,单位是毫秒)
 * @param {number} bufferMs 缓冲时间,单位毫秒,默认提前60秒判定过期,避免网络延迟导致的临界问题
 * @returns {boolean} true=需要刷新,false=令牌有效
 */
function isTokenExpired(expiryDate, bufferMs = 60 * 1000) {
  return Date.now() >= (expiryDate - bufferMs);
}

该判断逻辑完全在本地执行,不会触发远程请求,也不会因为令牌过期抛出错误。

修正后的路由代码

// 这里需要你先根据请求的userId从你的数据库中取出对应用户存储的expiryDate、refreshToken、accessToken
router.get("/api/tokenrefresh/:userId/:accessToken", async function (req, res) {
  // 1. 从数据库取该用户的令牌相关数据
  const userTokenData = await db.query('select expiry_date, refresh_token, access_token from user_tokens where user_id = ?', [req.params.userId]);
  if (!userTokenData) {
    return res.status(400).json({error: '用户令牌不存在'});
  }

  // 2. 本地判断是否过期
  const needRefresh = isTokenExpired(userTokenData.expiry_date);

  if (!needRefresh) {
    return res.json({
      refreshNeeded: false,
      token: userTokenData.access_token
    });
  }

  // 3. 主动刷新令牌逻辑(你可以根据自己的需求替换为自定义逻辑)
  oauth2Client.setCredentials({
    refresh_token: userTokenData.refresh_token
  });
  try {
    const {credentials} = await oauth2Client.refreshAccessToken();
    // 新的令牌记得更新到数据库
    await db.query('update user_tokens set access_token = ?, expiry_date = ? where user_id = ?', [
      credentials.access_token,
      credentials.expiry_date,
      req.params.userId
    ]);
    return res.json({
      refreshNeeded: true,
      token: credentials.access_token
    });
  } catch (e) {
    // 刷新失败一般是refresh_token也过期了,需要用户重新授权
    return res.status(401).json({error: '需要重新登录授权'});
  }
});
注意事项
  • 不要在路由中重复注册tokens事件监听器,该监听器全局注册一次即可,如果你是单实例处理多用户的场景,更建议直接调用refreshAccessToken方法主动获取新令牌,不要依赖事件回调
  • refresh_token默认长期有效,除非用户手动取消授权、超过6个月未使用、同一用户授权的refresh_token超过25个上限,才会失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:15:08