[英]How can I refresh the token with social-auth-app-django?
我使用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']})
但访问令牌只有3600秒有效,所以我需要刷新,我想我可以手动完成,但必须有一个更好的解决方案。 如何刷新access_token?
.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自定义):
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']
这基于get_auth_token
的方法AzureADOAuth2
。 我不认为这种方法可以在管道外访问,如果有任何办法,请回答这个问题。
在跟随访问令牌刷新时请求额外数据参数的问题之后,现在可以检查是否需要在每个后端更新access_token
。
在未来版本中( social-auth-core
> 0.2.1
),额外数据中将有一个新字段:
'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
。 小心了解后端的行为! 存在一个问题 ,我将在相关信息存在时更新答案。
此外, UserMixin
有一个名为access_token_expired
( code )的方法,可用于断言令牌是否有效( 注意 :此方法不适用于竞争条件,如@SCasey所指出的那样)。
在Python社交Auth - Core 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())}
谢谢@damio指出来。
对于版本1.0.1,@ NBajanca的更新几乎是正确的。
extra_data['expires_in']
就是现在
extra_data['expires']
所以代码是:
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']
EDIT @NBajanca指出,根据Oauth2文档, expires_in
在技术上是正确的。 对某些后端来说,这似乎可行。 使用expires
上述代码适用于v1.0.1中的provider="google-oauth2"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.