Google OAuth RefreshError,即使Django应用程序中存在Refresh Token



我的应用程序在Django上运行,Django allauth只允许通过Google OAuth注册/登录。因此,当用户注册时,他的社交oauth详细信息将保存到All auth social Accounts模型中,令牌数据保存在social Application Tokens模型中。

我们希望用户尽可能长时间登录,而无需定期授予/撤销访问权限。

问题1:默认到期时间设置为自注册时间起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片段

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。

我如何以编程方式扩展它以及扩展多长时间(它永远不会过期吗?(

您不能访问一小时后过期的令牌,这是标准设置。您可以使用刷新令牌来请求新的访问令牌,因为您需要

当已经有刷新令牌可用时,为什么会出现错误?根据文档,它会在到期前几分钟自动刷新令牌。我错过了什么?

刷新令牌用于在新访问令牌到期前大约五分钟请求新访问令牌。

google.auth.exceptions.RefreshError:凭据不包含刷新访问令牌所需的必要字段。

听起来你没有正确设置客户端对象。这里有些地方设置不正确。还要记住,如果你的应用程序仍在测试中,你的刷新令牌将在七天后过期,你需要重新授权你的测试用户。

creds = Credentials(
token=user_tokens.token,
refresh_token=user_tokens.token_secret,
client_id=app_google.client_id,
client_secret=app_google.secret,
)

相关内容

最新更新