Google OAuth RefreshError даже при наличии Refresh Token в приложении Django

Мое приложение, работающее на 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() в точности SAME AS ABOVE. Но чтобы получить любые данные Google/Youtube API, я получаю следующую ошибку в журналах сервера:

google.auth.exceptions.RefreshError: The credentials do not contain the necessary fields need to refresh the access token.

Вопрос 02: Когда токен Refresh уже доступен, почему возникает ошибка? Согласно документации, токен обновляется автоматически за несколько минут до истечения срока действия. Что я упускаю?

У меня уже было "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",
        },
    },
}

И фрагмент Django Views, связанный с OAuth:

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(youtube):
    request = youtube.liveBroadcasts().list(
        part="id, snippet, contentDetails, status",
        broadcastStatus="completed",
        broadcastType="all"
    )
    response = request.execute()
    return response

Примечание: Нет никакого front-end фреймворка, я использую django с django template UI.

Как я могу расширить это программно и на какой срок (может ли это быть никогда не истекающим?)

Токены доступа истекают через один час, это стандартная процедура. Вы можете использовать маркер обновления для запроса нового маркера доступа по мере необходимости

Когда токен Refresh уже доступен, почему возникает ошибка? Согласно документации, токен обновляется автоматически за несколько минут до истечения срока действия. Что я упускаю?

Токены обновления используются для запроса нового токена доступа примерно за пять минут до истечения срока его действия.

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,
)
Вернуться на верх