当 OAuth2Credential 对象尝试刷新其 access_token 时,有时会收到 invalid_grant 错误,然后无法刷新。我使用的代码基于 Google 的 python API 和 Mirror API 示例。
背景:
- 使用
oauth2client
模块进行身份验证和 OAuth2Credential 对象。 - 将 OAuth2Credential 对象腌制和 base64 存储到数据库中,就像 Google 自己的示例代码一样
- 使用
apiclient
模块调用 Mirror API - 此代码在 3 个不同的服务器上运行,在尝试发送时都出现相同的问题
- 我要求的范围是
"https://www.googleapis.com/auth/glass.timeline"
和"https://www.googleapis.com/auth/userinfo.profile"
- 我可以确认 access_type 设置为“离线”
- 我要求将approval_prompt 设为“强制”以防万一
以下是用于调用镜像 API 的代码:
from apiclient.discovery import build
http = credential.authorize(http=httplib2.Http())
service = build("mirror", "v1", http=http)
payload = <JSON_PAYLOAD_HERE>
service.timeline().insert(body=payload).execute()
调用服务时,它可能会发出 401,这意味着需要刷新 access_token。然后它调用刷新方法,除了 AccessTokenRefreshError 和错误invalid_grant。此时,凭证就如同废话了,因为 access_token 已过期,而 refresh_token 只会报同样的错误。
我已经看到页面说这可能是由于 NTP 问题而发生的,但我已经确认(甚至切换了 NTP 服务器)我的服务器是同步的。另一个记录在案的可能性是,在它们被回收之前只能存在 25 个刷新令牌,但我已经在 Credential 对象上实现了一个 store() 方法,因此当它被刷新时,新的凭证被保存在适当的位置(我可以确认这有效因为我在刷新时看到数据库中的新信息)。
由于我无法获得用户的凭据来开始按需展示此问题,因此除了“等待一段时间”之外,我无法解释重新创建问题的任何其他条件。我已经看到这个问题在验证并发送一个电话后不久就发生了,一直到一百个电话后的一周时间。
目前解决问题的唯一方法是要求用户重新授权,但这不是解决方案,因为我希望在没有用户交互的情况下离线使用 api。我也无法通知用户他们需要重新授权。