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

Getting access token from refresh token failing with invalid_grant error, and Bad Request OR Token has been expired or revoked as error description

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

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

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

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

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

问题

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

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

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

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

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

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

已更改密码

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

用户撤消了访问权限

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

申请状态。

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

刷新访问令牌给刷新令牌。

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

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

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

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

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