使用存储的refresh_token调用Google Calendar API运行数天后报invalid grant错
Google日历freebusy查询refresh_token报invalid grant错误解决方案
错误触发原因
你遇到的invalid grant错误大概率出现在oauth2Client.getAccessToken()步骤,也就是用存储的refresh_token兑换访问凭证的环节,符合Google OAuth2的凭证规则,常见触发场景如下:
- 用户主动撤销了应用授权:用户在Google账号「安全 - 第三方账号访问」页面手动取消了对你应用的授权,对应refresh_token直接失效
- refresh_token自然过期:如果refresh_token连续6个月没有被调用过会自动失效;同一个Google账号对同一个OAuth客户端最多保留50个有效refresh_token,超出限额后最早生成的会被自动吊销
- 账号安全策略触发吊销:如果是Google Workspace账号,用户修改登录密码、域管理员调整安全规则、或者域管理员直接封禁你的应用访问权限,都会批量吊销已发放的refresh_token
- OAuth客户端凭证变更:如果你后续在Google Cloud控制台修改过对应项目的OAuth客户端ID、客户端密钥,此前生成的所有refresh_token都会全部失效
修复方案
- 先确认无效refresh_token对应用户的授权状态,引导用户重新走OAuth授权流程获取新的refresh_token替换数据库内的旧值
- 调整你的定时任务逻辑,捕获
invalid grant错误后直接触发告警,不要重复用失效的refresh_token发起请求,避免触发Google接口的限流规则 - 如果你的服务对接大量Google用户,建议在数据库内给refresh_token加状态标记,检测到失效后直接标记为无效,后续不再调用
代码优化示例
你可以调整原有代码的错误捕获分支,做更精细的处理:
try { console.debug('Setting Oauth credentials with refresh token ' + refreshToken); oauth2Client.setCredentials({ refresh_token: refreshToken // 从数据库读取的refresh_token }); google.options({ auth: oauth2Client }); const tokens = await oauth2Client.getAccessToken(); const calendar = google.calendar('v3', oauth2Client); freeBusy = await calendar.freebusy.query(freeBusyBody); } catch (error) { console.error('native calendar freeBusy API' + error ); // 新增invalid grant错误的特殊处理 if (error.message.includes('invalid_grant')) { console.error(`refresh_token ${refreshToken} 已失效,请通知用户重新授权`); // 这里可以加逻辑更新数据库内该refresh_token的状态为失效,同时触发告警 // 不需要继续抛错中断整个定时任务的话可以注释下面的throw } throw new Error( error ); }
内容的提问来源于stack exchange,提问作者aknoefel
相关产品推荐
相关产品推荐

