如何使用socialauthappDjango刷新令牌?

2024-04-25 19:22:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Python Social Auth - Django登录我的用户。在

我的后端是Microsoft,所以我可以使用Microsoft Graph,但我不认为它是相关的。在

Python Social Auth处理身份验证,但现在我想调用API,为此,我需要一个有效的访问令牌。 按照use cases我可以得到这个:

social = request.user.social_auth.get(provider='azuread-oauth2')
response = self.get_json('https://graph.microsoft.com/v1.0/me',
                         headers={'Authorization': social.extra_data['token_type'] + ' ' 
                                                   + social.extra_data['access_token']})

但是访问令牌只在3600秒内有效,所以我需要刷新,我想我可以手动完成,但肯定有更好的解决方案。 如何刷新access_令牌?在


Tags: django用户tokenauth身份验证apidataget
3条回答

.get_access_token(strategy)如果令牌过期,则自动刷新它。你可以这样使用它:

from social_django.utils import load_strategy
#...
social = request.user.social_auth.get(provider='google-oauth2')
access_token = social.get_access_token(load_strategy())

social.apps.django_app.utils使用load_strategy()

social = request.user.social_auth.get(provider='azuread-oauth2')
strategy = load_strategy()
social.refresh_token(strategy)

现在可以从social.extra_data['access_token']检索更新的access_token。在

最好的方法可能是检查是否需要更新(为AzureAD Oauth2定制):

^{pr2}$

这是基于AzureADOAuth2get_auth_token方法。我不认为这种方法在管道外是可以访问的,如果有任何方法可以这样做,请回答这个问题。在

更新

更新1-2017年1月20日

Issue请求一个额外的数据参数以及访问令牌刷新的时间之后,现在可以检查access_token是否需要在每个后端中更新。在

在将来的版本中,0.2.1对于social-auth-core,在额外数据中会有一个新字段:

'auth_time': int(time.time())

所以这是可行的:

def get_token(user, provider):
    social = user.social_auth.get(provider=provider)
    if (social.extra_data['auth_time'] + social.extra_data['expires']) <= int(time.time()):
        strategy = load_strategy()
        social.refresh_token(strategy)
    return social.extra_data['access_token']

注意:根据OAuth 2 RFC,所有响应都应该(这是一个推荐的参数)提供一个expires_in,但是对于大多数后端(包括azuread-oauth2),这个值被保存为expires。小心理解后端的行为! 关于这个的Issue存在,当答案存在时,我将用相关信息更新答案。在

更新2-2017年2月17日

另外,在UserMixin中有一个名为access_token_expiredcode)的方法,可以用来断言令牌是否有效(注意:正如@SCasey在this anwser中指出的那样,此方法不适用于竞争条件。在

更新3-2017年5月31日

Python Social Auth - Core v1.3.0get_access_token(self, strategy)中引入了storage.py。在

所以现在:

from social_django.utils import load_strategy

social = request.user.social_auth.get(provider='azuread-oauth2')
response = self.get_json('https://graph.microsoft.com/v1.0/me',
                     headers={'Authorization': '%s %s' % (social.extra_data['token_type'], 
                                                          social.get_access_token(load_strategy())}

谢谢你指出这一点。在

@NBajanca的更新对于版本1.0.1几乎是正确的。在

extra_data['expires_in']

现在是

^{pr2}$

所以代码是:

def get_token(user, provider):
    social = user.social_auth.get(provider=provider)
    if (social.extra_data['auth_time'] + social.extra_data['expires']) <= int(time.time()):
        strategy = load_strategy()
        social.refresh_token(strategy)
    return social.extra_data['access_token']

我还建议从计算中减去任意时间量,这样我们就不会遇到这样的竞争情况:我们在到期前检查了令牌0.01s,然后因为过期后发送了请求而出现错误。为了安全起见,我喜欢增加10秒,但这可能是过度的:

def get_token(user, provider):
    social = user.social_auth.get(provider=provider)
    if (social.extra_data['auth_time'] + social.extra_data['expires'] - 10) <= int(time.time()):
        strategy = load_strategy()
        social.refresh_token(strategy)
    return social.extra_data['access_token']

编辑 @NBajanca指出,根据Oauth2文档,expires_in在技术上是正确的。对于某些后端,这似乎是可行的。上面使用expires的代码是从v1.0.1开始使用provider="google-oauth2"的代码

相关问题 更多 >