Как использовать django-allauth для Google API?

Как django-allauth реализовано получение авторизации с использованием Oauth2 для Google API (в моем случае Gmail API)? Кроме того, я собираюсь реализовать это отдельно от использования django-allauth, чтобы пользователи могли входить в систему с помощью Google, поэтому мне нужно будет сохранить это отдельно, а также вызвать его в представлении.

Спасибо!

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

Затем вы можете использовать django-allauth для настройки аутентификации через Google с сохранением токенов. Укажите необходимые параметры для gmail scope. Затем используйте эти токены для работы с GmailAPI.

Сначала вам нужно установить некоторые настройки, это описано в этом документе (SOCIALACCOUNT_STORE_TOKENS константа). Примерно так:

#  settings.py
SOCIALACCOUNT_STORE_TOKENS = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True

Также настройте “access_type”: “offline” в настройках поставщика google, как описано здесь:

Вы должны установить для AUTH_PARAMS['access_type'] значение offline, чтобы получать токен обновления при первом входе в систему и при запросах повторной аутентификации (который необходим для обновления токенов аутентификации в фоновом режиме, без участия браузера пользователя). Если этот параметр не указан, Google по умолчанию использует online.

Теперь, после того как пользователь войдет в вашу систему через учетную запись google, будет создана запись в базе данных с его учетными записями access_token и refresh_token (token_secret in db_table). Вы можете проверить это в интерфейсе администратора в этой таблице:

admin

Чтобы использовать GmailAPI, вам нужен google идентификатор пользователя и его access_token, это можно найти следующим образом:

def get_user_google_tokens(request: HttpRequest, limit: int = 1) -> list[dict]:
    from allauth.socialaccount.models import SocialToken
    from django.db import models

    user_google_tokens = list(
        SocialToken.objects
        .filter(account__provider='google', account__user_id=request.user.pk)
        .annotate(google_user_id=models.F('account__uid'))
        .order_by('-expires_at')
        .values('token', 'token_secret', 'expires_at', 'google_user_id')[:limit]
    )
    print(user_google_tokens)
    #  [
    #   {'token': '...', 
    #    'token_secret': '...', 
    #    'expires_at': datetime.datetime(2025, 2, 7, 16, 38, 16, 611588, tzinfo=datetime.timezone.utc), 
    #    'google_user_id': '...'}
    #  ]
    return user_google_tokens

Обратите внимание, что по умолчанию access_token действует недолго - один час. Подробнее об этом можно прочитать здесь. Когда срок действия вашего access_token истечет, вам нужно будет обновить его, используя refresh_token (token_secret), и записать новый access_token в базу данных, изменив существующую запись. Вот пример того, как выполнить обновление. Также обратите внимание, что иногда вы не сможете обновить токены с помощью refresh_token.

Вот пример запроса на обновление токена с использованием Postman. Но вы, вероятно, будете использовать какую-нибудь библиотеку для http запросов на python. Или какой-нибудь готовый клиент, если уж на то пошло. django-allauth похоже, он не может обновлять токены, но я точно не знаю, я этого не проверял.

postman

Вернуться на верх