How to store the refresh token in HttpOnly cookie with Google OAuth2 (PKCE flow) in Django?
I'm using Django with drf_social_oauth2
and oauth2_provider
for Google OAuth2 authentication. I’ve successfully implemented the PKCE authorization flow.
Step 1: Frontend redirects to:
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
Step 2: Frontend exchanges code at:
POST /api/v1/o/token/
.
Backend responds with:
{
"access_token": "...",
"expires_in": 36000,
"refresh_token": "...", ← this is what I want to move into a cookie
...
}
My configuration:
# 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 = "/"
What works:
- PKCE is working.
- Google OAuth2 authorization is integrated using
social-auth-app-django
anddrf-social-oauth2
. - I can extract the original Google access_token from the user's social_auth.extra_data.
What I want: I want to store the refresh_token in a secure HttpOnly cookie instead of returning it in the JSON response — to reduce XSS risks.
I would be grateful for any advice, code examples on how to solve this, or references to sources where a solution can be found.