从刷新令牌获取访问令牌失败并显示 invalid_grant 错误,并且错误请求或令牌已过期或被撤销作为错误描述

问题描述

使用 Java OAuth2 客户端库:scribe 1.2.0 (https://github.com/scribejava/scribejava)

我能够从授权代码获取刷新令牌(即,通过使用 client_id、client_secret、code、scope、grant_type (authorization_code)、redirect_uri 参数对 https://accounts.google.com/o/oauth2/token 进行 POST 调用)。我已经在数据库中保留了刷新令牌。 我们支持驱动器和日历范围 => 因此,我确实为每个用户(电子邮件)存储了两个刷新令牌

然后客户端将调用 API 来获取访问令牌(然后我使用 refresh_token、grant_type (refresh_token)、client_id 和 client_secret 对 https://accounts.google.com/o/oauth2/token 进行 POST 调用)。并且调用成功。 IE;快乐正常路径有效。

但最终从刷新令牌获取新的访问令牌失败并显示 invalid_grant 错误代码错误请求 OR 令牌已过期或撤销作为错误)(如 2 天或 3 天等)

请注意,刷新令牌不会被用户代码明确撤销或失效。密码未更改。代码没有改变。客户端 ID 和机密没有改变。我有点迷茫。

问题

  1. 既然刷新令牌应该一个持久令牌,为什么我的应用程序无法从刷新令牌中获取新的访问令牌?它只是在 2 到 3 天内失败了 - 并且它在舞台和生产环境中经常发生。

  2. 是否根据范围(驱动器和日历)存储两个刷新令牌 - 每个用户(电子邮件)问题(即,一旦发出第二个刷新令牌,前一个刷新令牌就会过期)? [不应该 - 我知道每个用户和客户都有限制,每个用户对所有客户都有限制。但是,2 太低而无法达到该限制。]

回答 终于能够解决它,请参阅下面评论的答案 - 它与具有不同范围的同一电子邮件的两个刷新令牌有关,并使其中一个无效。

从刷新令牌中获取访问令牌 - PostMan

Getting access token from Refresh token - PostMan

从授权码中获取刷新令牌 - PostMan

Getting refresh token from authorization code - PostMan

相关问题:Google token refresh returns "Token has been expired or revoked." Since couple of days Refresh token has been automatically expired

解决方法

更改密码

您的刷新令牌可能会过期有多种原因。我们可以锁定的第一个原因是用户更改了密码,如果您使用的是 gmail 范围,并且用户更改了密码,这将导致所有未完成的刷新令牌过期。

用户撤销访问

如果用户直接通过其 Google 帐户撤销您的访问权限,这也会撤销您的刷新令牌。

申请状态。

现在你的应用还在谷歌云控制台上测试吗?通过验证过程,您是否已将其移至已发布?如果没有,那么您的刷新令牌可能会在大约两周后到期,尽管时间框架可能已经改变,因为这似乎是 Google 在过去几个月一直在努力的事情,并且没有官方消息。

刷新访问令牌提供刷新令牌。

实际上可能是这种情况的另一个原因,当您刷新访问令牌时,它是否会返回一个新的刷新令牌。有时我会这样做。始终检查这是否与您之前使用的刷新令牌相同,如果注意,则它是一个新令牌,您应该存储新令牌。有关原因的更多信息,请参阅下一点。

未完成刷新令牌的最大数量。

当用户使用离线访问授权您的应用程序时,您将获得一个刷新令牌,如果用户再次授权您的应用程序,您将获得另一个刷新令牌。您最多可以继续这样做 50 次,所有 50 个刷新令牌都将继续工作。一旦你超过了 50 的神奇数字,那么创建的第一个数字就会过期。这就是为什么确保始终在数据库中存储用户的最新刷新令牌很重要的原因。

,

基本上,如果您的应用针对同一用户 (Gmail) 具有多个不同范围的刷新令牌,则使其中一个无效将使所有令牌无效。

事实证明这是个问题,因为我们根据范围(例如驱动器、日历、联系人等)维护不同的刷新令牌