如何使用 social-auth-app-django 刷新令牌?
How can I refresh the token with social-auth-app-django?
我使用 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_token 刷新?
使用 load_strategy()
在 social.apps.django_app.utils
:
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']
这是基于 AzureADOAuth2
中的 get_auth_token
方法。我认为这种方法在管道外是无法访问的,如果有任何方法,请回答这个问题。
更新
更新 1 - 2017 年 1 月 20 日
在 Issue 之后请求一个带有访问令牌刷新时间的额外数据参数,现在可以检查 access_token
是否需要在每个后端更新。
在未来的版本中(>0.2.1
for the 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_expired
的方法(code) that can be used to assert if the token is valid or not (note: this method doesn't work for race conditions, as pointed out in by @SCasey)。
更新 3 - 2017 年 5 月 31 日
在 Python Social 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())}
感谢 @damio 指出。
@NBajanca 的更新对于版本 1.0.1 几乎是正确的。
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.01 秒检查令牌然后得到错误,因为我们在过期后发送了请求。为了安全起见,我喜欢加 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 指出 expires_in
根据 Oauth2 文档在技术上是正确的。似乎对于某些后端,这可能有效。从 v1.0.1
开始,上面使用 expires
的代码适用于 provider="google-oauth2"
.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())
我使用 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_token 刷新?
使用 load_strategy()
在 social.apps.django_app.utils
:
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']
这是基于 AzureADOAuth2
中的 get_auth_token
方法。我认为这种方法在管道外是无法访问的,如果有任何方法,请回答这个问题。
更新
更新 1 - 2017 年 1 月 20 日
在 Issue 之后请求一个带有访问令牌刷新时间的额外数据参数,现在可以检查 access_token
是否需要在每个后端更新。
在未来的版本中(>0.2.1
for the 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_expired
的方法(code) that can be used to assert if the token is valid or not (note: this method doesn't work for race conditions, as pointed out in
更新 3 - 2017 年 5 月 31 日
在 Python Social 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())}
感谢 @damio 指出。
@NBajanca 的更新对于版本 1.0.1 几乎是正确的。
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.01 秒检查令牌然后得到错误,因为我们在过期后发送了请求。为了安全起见,我喜欢加 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 指出 expires_in
根据 Oauth2 文档在技术上是正确的。似乎对于某些后端,这可能有效。从 v1.0.1
expires
的代码适用于 provider="google-oauth2"
.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())