赞
踩
我最近一直在讨论这个问题.
一些背景
>使用oauth2client库管理用户的令牌.令牌用于定期和同时执行各种后台任务.
>每当其中一个任务即将为用户运行时,我们从存储中获取Credentials对象,并在到期时间约为5分钟时进行刷新.否则,重新使用当前访问令牌.
>有时,1个用户的多个任务同时运行
>一段时间一切正常,令牌正常刷新
>在这些尝试刷新之一中,间歇性地并且看似异常突然,返回“invalid_grant”错误,并且它使存储中的刷新令牌完全无效. (何时/如何/为什么会发生这是我希望通过这个问题弄清楚的)
搜索周围,有很多关于这个问题的线程/报告.但到目前为止我发现的所有内容都不适用于我们的案例.我将尝试列出我到目前为止所研究的内容:
>用户已撤消权限
这个是最明显的,记录最多且易于重现的,但不幸的是,在我们的案例中,我们的用户(或我们自己,在测试时)根本没有撤销权限.
>刷新“旧”访问令牌
起初我认为用户一次只能有一个有效的访问令牌. That is false,并在OAuth2 Playground上验证.
每个用户每个用户最多有25个活动令牌.达到该限制后,即使其过期日期尚未过期,旧的访问令牌也会以静默方式失效.
这对我们来说也是一个死胡同,因为我们的问题在刷新时发生,而不是使用最旧的访问令牌.此限制仅影响访问令牌,而不影响刷新令牌.
>在很短的时间内请求刷新太多次
根本没有记录.只提及没有参考.试图通过在7秒内刷新25次来模仿它,但一切顺利.但没有参考,这是一个黑暗中的镜头.我们的后台任务每隔几分钟最多只需10次.继续.
>并发刷新会导致令牌成功的竞争条件
我正在努力解决这个问题.我们无法轻易复制它的事实是一种痛苦.我真的很想知道我错过了什么可能导致这种情况?
这是我们的刷新代码:
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。