[英]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.