Express.js后端调用Google新Place API时OAuth刷新令牌失败需每日重授权
错误信息
Token is expiring, refreshing...
Failed to refresh token: {"error":"invalid_grant","error_description":"reauth related error (invalid_rapt)","error_uri":"https://support.google.com/a/answer/9368756","error_subtype":"invalid_rapt"}
Authorize this app by visiting this URL: URL here.
核心问题分析
这个invalid_rapt错误是Google重认证机制触发的结果,加上你需要每日重新授权,本质是没有正确获取并维护长期有效的刷新令牌,或者OAuth流程配置存在缺陷。
具体解决步骤
必须请求离线访问权限
生成授权URL时,一定要添加access_type=offline参数,这是获取长期刷新令牌的前提。如果没有这个参数,Google只会返回短期访问令牌(有效期通常1小时),且无法刷新,过期后就必须重新授权。Express中示例代码:const authUrl = oauth2Client.generateAuthUrl({ access_type: 'offline', // 关键参数,不可省略 scope: ['https://www.googleapis.com/auth/places'], // 对应Place API的权限标识 prompt: 'consent' // 首次授权强制用户确认,确保能拿到刷新令牌 });持久化存储刷新令牌
授权成功后得到的refresh_token必须存入数据库、Redis这类持久化存储中,不能存在内存里。Express服务重启或进程回收后,内存中的令牌会丢失,导致无法触发自动刷新流程,只能重新引导用户授权。检查刷新令牌的请求逻辑
刷新令牌时要确保请求参数完全正确:- 请求体必须包含
refresh_token、client_id、client_secret,且grant_type=refresh_token - 不要使用已被吊销、或用户已取消授权的刷新令牌(这种情况只能重新引导用户授权)
- 请求体必须包含
排查Google Cloud控制台配置
- 确认你的应用采用授权码流(Authorization Code Flow),这是后端服务调用Google API的标准流程,不要使用隐式流
- 检查重定向URI和代码中配置的完全一致,否则授权后无法正确获取令牌
- 生产环境建议完成应用验证,未验证的应用可能会被限制令牌有效期
补充说明
授权操作本身确实是一次性的,但前提是你正确获取了刷新令牌并持续维护。只要刷新令牌有效且配置正确,后端就能自动刷新访问令牌,无需用户重复授权。如果遇到invalid_rapt且刷新令牌无效,可能是用户修改了账号安全设置、撤销了应用授权,或者Google触发了强制重认证,这种情况才需要用户重新授权。
内容的提问来源于stack exchange,提问作者yassir agh

