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

使用Google离线授权码兑换Access/Refresh Token时遇invalid_grant错误求助

解决Google OAuth授权码兑换令牌时的invalid_grant错误

看起来你在把Google OAuth授权码兑换成Access/Refresh Token时卡在了invalid_grant错误上——这确实是OAuth流程里挺让人头疼的问题,我结合你的操作细节给你梳理几个关键排查方向:

1. 确保redirect_uri完全一致

这是最常见的触发原因!你需要保证三个地方的redirect_uri完全一模一样:

  • Google Cloud控制台中你的OAuth客户端配置里的“已授权的重定向URI”
  • 你获取授权码时(不管是调用grantOfflineAccess还是构造授权链接)使用的redirect_uri
  • Postman请求令牌接口时传的redirect_uri

注意细节:http/https不能混、域名后的端口要对、结尾的斜杠有没有加、甚至大小写(虽然大部分情况不敏感,但严格匹配更保险),哪怕差一个字符都会返回invalid_grant。

2. 授权码只能用一次且时效性极强

Google的授权码有效期只有10分钟左右,而且只能被兑换一次。如果你是重复使用同一个授权码,或者拿到码之后隔了很久才去调用令牌接口,肯定会触发错误。建议每次兑换前都重新获取新的授权码,拿到后立刻发起兑换请求。

3. 检查OAuth客户端类型与配置匹配

你提到要在服务器端模拟用户下载Fitness数据,要确认你在Google Cloud控制台创建的是Web应用类型的OAuth客户端(不是桌面应用或其他类型)。另外,务必先在控制台里启用Google Fitness API——如果API没启用,哪怕权限配置正确也会导致授权失败。

4. 验证请求格式与参数正确性

在Postman里请求令牌接口时,必须注意:

  • 请求方法是POST
  • 内容类型选择x-www-form-urlencoded(不能用JSON或其他格式)
  • 参数里的client_id要完整(包括.apps.googleusercontent.com后缀),client_secret要和控制台里的完全一致,不要有多余空格或字符

给你一个标准的请求参数示例(替换成你的实际值):

code=刚获取的授权码
client_id=your-client-id.apps.googleusercontent.com
client_secret=your-client-secret
redirect_uri=https://your-redirect-url.com/callback
grant_type=authorization_code

5. 再次确认时间同步的准确性

你已经做了NTP同步,但还是要确保你的服务器时间和Google服务器的时间差在5分钟以内——OAuth的令牌验证对时间戳非常敏感,微小的时间偏差都可能导致invalid_grant。可以直接访问time.google.com对比系统时间。

6. 排查grantOfflineAccess的隐藏配置

你用gapi.client.init初始化时没有指定redirect_uri,这时候gapi会默认使用当前页面的URL作为重定向地址。要确保这个页面URL已经被添加到Google控制台的“已授权的重定向URI”列表里,否则获取到的授权码本身就是无效的,自然兑换失败。

另外,如果你是用普通Google账号(非Google Workspace账号),是无法使用域范围模拟(impersonate)的,只能通过用户手动授权获取refresh_token后,在服务器端保存并使用它来刷新access_token——这个流程是没问题的,只要前面的配置都正确就能成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:56:02