【问题标题】:Google OAuth RefreshError even with Refresh Token present in the Django app即使 Django 应用程序中存在刷新令牌,Google OAuth RefreshError
【发布时间】: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


    【解决方案1】:

    我如何以编程方式扩展它以及持续多长时间(它可以永不过期吗?)

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

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

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

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

    听起来您没有正确设置客户端对象。这里的某些东西设置不正确。另请记住,如果您的应用仍在测试中,您的刷新令牌将在 7 天后过期,您需要重新授权测试用户。

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

    【讨论】:

    • 我的 Google OAuth 处于测试阶段,但一小时后仍会弹出令牌刷新错误。
    • 如果刷新错误在一个小时后弹出,那么您的系统没有使用刷新令牌来刷新访问令牌。检查您是否正确加载了该凭据对象。我真的认为这应该是 refresh_token=user_tokens.refresh_token
    • 检查了 Admin 中的 Social Application Token 模型,以及 DB 模式。 Refresh Token 字段名其实是token_secret
    猜你喜欢
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2017-06-09
    相关资源
    最近更新 更多