Как сохранить токен обновления в HttpOnly cookie с помощью Google OAuth2 (PKCE flow) в Django?

Я использую Django с drf_social_oauth2 и oauth2_provider для аутентификации Google OAuth2. Я успешно реализовал процесс авторизации PKCE.

Шаг 1: Интерфейс перенаправляет на: GET /api/v1/o/authorize/?client_id=<client_id>&response_type=code&redirect_uri=http://127.0.0.1:5173/callback&code_challenge=<challenge>&code_challenge_method=S256

Шаг 2: Интерфейс обменивается кодом по адресу: POST /api/v1/o/token/. Серверная часть отвечает следующим образом:

{
  "access_token": "...",
  "expires_in": 36000,
  "refresh_token": "...",  ← this is what I want to move into a cookie
  ...
}

Моя конфигурация:

# urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/v1/o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
]

# settings.py (snippets)
INSTALLED_APPS = [
    ...
    'oauth2_provider',
    'social_django',
    'drf_social_oauth2',
]

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'social_core.backends.google.GoogleOAuth2',
    'drf_social_oauth2.backends.DjangoOAuth2',
)

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '<your-client-id>'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '<your-client-secret>'

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
        "drf_social_oauth2.authentication.SocialAuthentication",
    ),
}

LOGIN_REDIRECT_URL = "/"

Что работает:

  1. PKCE работает.
  2. Авторизация в Google OAuth2 интегрирована с использованием social-auth-app-django и drf-social-oauth2.
  3. Я могу извлечь исходный Google access_token из пользовательских данных social_auth.extra_data.

Что я хочу: Я хочу сохранить refresh_token в защищенном файле cookie HttpOnly вместо того, чтобы возвращать его в JSON—ответе - чтобы уменьшить риски XSS.

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

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