如何使用social-auth-app-django刷新令牌?

NBa*_*nca 2 python django python-social-auth

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

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

Python Social Auth处理身份验证,但现在我想调用API,为此,我需要一个有效的访问令牌.根据用例我可以得到:

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']})
Run Code Online (Sandbox Code Playgroud)

但访问令牌只有3600秒有效,所以我需要刷新,我想我可以手动完成,但必须有一个更好的解决方案.如何刷新access_token?

NBa*_*nca 8

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

social = request.user.social_auth.get(provider='azuread-oauth2')
strategy = load_strategy()
social.refresh_token(strategy)
Run Code Online (Sandbox Code Playgroud)

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

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

def get_azuread_oauth2_token(user):
    social = user.social_auth.get(provider='azuread-oauth2')
    if social.extra_data['expires_on'] <= int(time.time()):
        strategy = load_strategy()
        social.refresh_token(strategy)
    return social.extra_data['access_token']
Run Code Online (Sandbox Code Playgroud)

这是基于该方法get_auth_tokenAzureADOAuth2.我不认为这种方法可以在管道外访问,如果有任何办法,请回答这个问题.

更新

更新1 - 20/01/2017

在跟随访问令牌刷新时请求额外数据参数的问题之后,现在可以检查是否access_token需要在每个后端更新.

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

'auth_time': int(time.time())
Run Code Online (Sandbox Code Playgroud)

这样可行:

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']
Run Code Online (Sandbox Code Playgroud)

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

更新2 - 17/02/17

另外,在UserMixin被调用access_token_expired(代码)中有一个方法可以用来断言令牌是否有效(注意:这种方法不适用于竞争条件,正如@SCasey本指南中所指出的那样).

更新3 - 31/05/17

Python社交Auth - Core v1.3.0 get_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())}
Run Code Online (Sandbox Code Playgroud)

谢谢@damio指出来.


dam*_*mio 8

.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())
Run Code Online (Sandbox Code Playgroud)