【发布时间】:2022-02-10 01:16:36
【问题描述】:
我在 Django 上使用 Django allauth 运行的应用程序仅允许通过 Google OAuth 进行注册/登录。因此,当用户注册时,他的社交 oauth 详细信息会保存到 All-auth Social Accounts 模型中,而令牌数据保存在 Social Application Tokens 模型中。
我们希望用户尽可能长时间地登录,而不是定期授予/撤销访问权限。
问题一:默认有效期设置为从注册时间算起1小时。如何以编程方式扩展它以及持续多长时间(它可以永不过期吗?)
目前有用户5:00登录,我从credentials.to_json()得到以下数据:
{
"token": "ya29.A0ARrdaM8YXPM35RXPv7UK-pXLZvWG49T-MgCZ5wMse2ADMXOZJOWFJKMaq1PkobADLptM5YX5mnrliS2yCCESqCk0NTaZJkfe6inK94j6WQMFZWIT_xRyBTOX4W3dUEiuLhHFpQcD5vS-x_Y22pUzxwgI23pp",
"refresh_token": "1//0gYC8oucHhTBVCgYIARAAGBASNwF-L9IrCG7c5IJCBMVznUrytGEFsJbsObAFvmNBoQbHHGA1KESyBWgmudEVogbes8ski87q_5g",
"client_id": "blablabla.apps.googleusercontent.com",
"client_secret": "xyzsecret"}
没有其他数据返回。
在 6:05,credentials.to_json() 与 与上述相同完全相同。
但要获取任何 Google/Youtube API 数据,我在服务器日志中收到以下错误:
google.auth.exceptions.RefreshError: The credentials do not contain the necessary fields need to refresh the access token.
问题02:当已经有可用的刷新令牌时,为什么会出现错误? 根据文档,它会在到期前几分钟自动刷新令牌。我错过了什么?
我已经在提供程序设置中有"access_type": "offline"。我也尝试添加"prompt": "consent",,但没有效果。
Django 设置:
INSTALLED_APPS = [
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.google",
...
]
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
SOCIALACCOUNT_PROVIDERS = {
"google": {
"SCOPE": [
"profile",
"email",
"https://www.googleapis.com/auth/youtube",
"https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/youtube.upload",
"https://www.googleapis.com/auth/youtube.force-ssl",
],
"AUTH_PARAMS": {
"access_type": "offline",
"prompt": "consent",
},
},
}
以及与 OAuth 相关的 Django Views sn-p:
import googleapiclient.discovery
import googleapiclient.errors
from allauth.socialaccount.models import SocialAccount, SocialApp
from google.oauth2.credentials import Credentials
def get_credentials_google(user):
app_google = SocialApp.objects.get(provider="google")
account = SocialAccount.objects.get(user=user)
user_tokens = account.socialtoken_set.first()
creds = Credentials(
token=user_tokens.token,
refresh_token=user_tokens.token_secret,
client_id=app_google.client_id,
client_secret=app_google.secret,
)
return creds
def get_youtube_account(user):
api_service_name = "youtube"
api_version = "v3"
credentials = get_credentials_google(user)
youtube = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials
)
return youtube
def get_youtube_videos(request):
youtube = get_youtube_account(request.user)
request = youtube.liveBroadcasts().list(
part="id, snippet, contentDetails, status",
broadcastStatus="completed",
broadcastType="all"
)
response = request.execute()
return response
注意:我使用 django 和 django 模板 UI 没有前端框架。
【问题讨论】:
标签: django oauth-2.0 google-oauth django-allauth google-api-python-client