"invalid_grant"的情况包括:刷新访问令牌时出错? [英] Circumstances of the "invalid_grant" error when refreshing an access token?

查看:1174
本文介绍了"invalid_grant"的情况包括:刷新访问令牌时出错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我一直在努力解决这个问题.

I've been pulling my hair out over this issue lately.

一些背景

  • 使用 oauth2client 库来管理用户令牌.这些令牌用于定期并同时执行各种后台任务.
  • 每次要为用户运行这些任务之一时,我们都会从存储中获取Credentials对象,并在到期约5分钟后进行刷新.否则,将重新使用当前的访问令牌.
  • 有时会为1个用户同时运行多个任务
  • 一段时间后一切正常,令牌会正常刷新
  • 间歇性地并且看似出乎意料,在这些尝试的刷新之一期间,返回"invalid_grant"错误,它完全使存储中的刷新令牌无效. (希望何时,如何/为什么发生此问题)
  • using the oauth2client library to manage tokens of users. The tokens are used to do a variety of background tasks periodically and concurrently.
  • each time one of these tasks is about to run for a user, we get the Credentials object from storage and do a refresh if the expiry is ~5 minutes away. Otherwise the current access token is re-used.
  • it happens that sometimes multiple tasks for 1 user are running at the same time
  • for a while everything works fine, the tokens get refreshed normally
  • intermittently and seemingly out of the blue, during one of these attempted refresh, an "invalid_grant" error is returned, and it completely invalidates the refresh token in storage. (When/how/why it happens is what I hope to figure out with this question)

四处搜寻,有很多关于此问题的线索/报告.但是到目前为止,我发现的所有内容都不适用于我们的案例.我将尝试列出到目前为止我研究过的内容:

Searching around, there are a lot of threads/reports about this issue. But all I've found so far don't apply to our case. I'll try to list the ones I have looked into so far:

  1. 用户已撤消权限

这是最明显,最有据可查的,并且易于复制,但不幸的是,在我们的情况下,我们的用户(或我们自己,在测试中)根本没有撤消权限.

This one is the most obvious, most documented and is easily reproducible, but unfortunately in our case our users (or ourselves, while testing), didn't revoke permissions at all.

  1. 刷新旧"访问令牌

起初,我认为一个用户一次只能有1个有效的访问令牌. 这是错误的,并在OAuth2 Playground上进行了验证.

At first I thought that there can only be 1 valid access token at a time for a user. That is false, and verified on OAuth2 Playground.

  1. 用户的活动访问令牌过多

每个客户每个用户最多只能使用25个有效令牌.一旦达到该限制,即使尚未过期,较旧的访问令牌也会以静默方式失效.

There's a limit of 25 active tokens per user per client. Once that limit is reached, older access tokens are invalidated silently, even if their expiration date hasn't passed yet.

对于我们来说,这也是一个死胡同,因为刷新时会发生问题,而不是使用最早的访问令牌.而且此限制仅影响访问令牌,而不会刷新令牌.

This is a dead end for us as well, since our issue happens when refreshing, not using the oldest access token. And this limit only affects access tokens, not refresh tokens.

  1. 在短时间内请求刷新太多次

完全没有记录.仅附带提及而没有参考.试图通过在7秒内刷新25次来模拟它,但是一切进展顺利.但是没有参考,这是一个黑暗的镜头.而且我们的后台任务每几分钟最多只能完成大约10个任务.继续前进.

Not documented at all. Only mentioned in passing with no references. Tried to emulate it by doing a refresh 25 times in 7 seconds, but all went well. But with no references, this is a shot in a dark. And our background tasks only ever max at ~10 tasks every several minutes. Moving on.

  1. 并发刷新会导致令牌成功的竞争状况

我已经在这里问了一个问题,但事实并非如此.通过同时运行两个计划的任务在AppEngine上进行了测试.

I've asked a question here, but this wasn't the case. Tested on AppEngine by running two tasks scheduled at the same time.

我正在尽力解决这个问题.我们无法轻易复制它的事实令人痛苦.我真的很想了解我可能错过的原因是什么?

I'm at my wit's end trying to pin down this issue. The fact that we can't readily reproduce it is a pain. I'd really like some insight on what could possibly be causing this that I've missed?

这是我们的刷新代码:

def refresh_oauth_credentials(user, credentials, force=False):
    if not credentials:
        return None
    logging.debug(credentials.token_expiry)
    do_refresh = credentials._expires_in() < 300
    if force or do_refresh:
        h = httplib2.Http()
        try:
            logging.debug('Refreshing %s\'s oauth2 credentials...' % user.email)
            credentials.refresh(h)
        except AccessTokenRefreshError:
            logging.warning('Failed to refresh.')
            return None
    return credentials

推荐答案

该消息实际上是说刷新令牌无效(已过期,已撤销等)或与访问令牌请求的详细信息(用户,范围)不匹配.因此,在您的问题中,您说的是返回了"invalid_grant"错误,它使存储中的刷新令牌完全无效",这有点相反.刷新令牌由于某种原因而无效,这导致了无效授权".

The message is essentially saying the refresh token is either invalid (expired, revoked, etc) or doesn't match the access token request details (user, scope). So where in your question you said "an "invalid_grant" error is returned, and it completely invalidates the refresh token in storage", it's kinda the other way round, ie. the refresh token is invalid for some reason, and that is causing the "invalid grant".

如果在您的开发工作流程/测试期间,您正在为用户获取新的刷新令牌,那么在开发过程中我已经看到很多.

I've seen this a lot during development if during your dev workflow/testing you are getting new refresh tokens for a user.

这篇关于"invalid_grant"的情况包括:刷新访问令牌时出错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆