Токен обновления передается в теле ответа при регистрации, но не для входа в систему в Django

Я использую фреймворк Django REST с dj-rest-auth и django-allauth для аутентификации и авторизации с помощью JWTs. Из того, что я слышал, использование файлов cookie только для HTTP для хранения токенов - это безопасный подход, при котором токен доступа передается в теле ответа, а токен обновления передается браузеру в виде файла cookie.

Конечная точка входа в систему по умолчанию работает следующим образом, возвращая токен доступа в теле ответа и токены доступа и обновления в виде файлов cookie только для HTTP, а также csrftoken и sessionid. Однако конечная точка регистрации ведет себя иначе, она возвращает токены доступа и обновления в теле ответа и не возвращает ни один из них в виде файла cookie, но возвращает эти файлы cookie: сообщения, csrftoken, sessionid. Кто-нибудь знает, почему это может происходить и как я могу заставить регистрацию работать так же, как и вход в систему? Вот соответствующие части моего settings.py:

REST_AUTH = {
    "USE_JWT": True,
    "JWT_AUTH_COOKIE": "access-tkk",
    "JWT_AUTH_REFRESH_COOKIE": "refresh-tkk",
    # "JWT_AUTH_SECURE": True,  # Use secure cookies in production for HTTPS only
    "JWT_AUTH_HTTPONLY": True,  # Secure HTTP-only cookies
    "REGISTER_SERIALIZER": "authentication.serializers.CustomRegisterSerializer",
    "USER_DETAILS_SERIALIZER": "authentication.serializers.CustomUserDetailsSerializer",
}


SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=15),  # Short-lived access token
    "REFRESH_TOKEN_LIFETIME": timedelta(days=14),  # Longer-lived refresh token
    "ROTATE_REFRESH_TOKENS": True,  # Issue new refresh token on refresh
    "BLACKLIST_AFTER_ROTATION": True,  # Blacklist old refresh tokens
    "UPDATE_LAST_LOGIN": True,
    "ALGORITHM": "HS256",
    "AUTH_HEADER_TYPES": ("Bearer",),
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
}

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "dj_rest_auth.jwt_auth.JWTCookieAuthentication",
        "rest_framework.authentication.TokenAuthentication",
    ),
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
}

Чтобы регистрация в файлах cookie, доступных только для HTTP, выполнялась так же, как и возврат токенов для входа в систему, вам необходимо переопределить RegisterView по умолчанию, чтобы вручную настроить файлы cookie. Создайте пользовательский RegisterView

from dj_rest_auth.registration.views import RegisterView
from dj_rest_auth.jwt_auth import set_jwt_cookies
from rest_framework.response import Response
from rest_framework import status

class CustomRegisterView(RegisterView):
    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        
        # Check if the JWTs are present in response data
        if "access" in response.data and "refresh" in response.data:
            set_jwt_cookies(response, access_token=response.data["access"], refresh_token=response.data["refresh"])
        
        return response

Проблема:
dj-rest-auth логин устанавливает JWTS в файлах cookie только для HTTP, но не для регистрации - он возвращает токены только в теле ответа.

Причина:
RegisterView не включает логику установки файлов cookie, как это делает LoginView.

Чтобы исправить : - Чтобы установить файлы cookie JWT при регистрации (так же, как при входе в систему), расширьте RegisterView и вручную установите файлы cookie.

Создайте пользовательский RegisterView:

# views.py:

from dj_rest_auth.registration.views import RegisterView
from dj_rest_auth.jwt_auth import set_jwt_cookies
from rest_framework import status

class CustomRegisterView(RegisterView):
    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        if response.status_code == status.HTTP_201_CREATED:
            access = response.data.get("access")
            refresh = response.data.get("refresh")
            if access and refresh:
                set_jwt_cookies(response, access, refresh)
        return response
# urls.py:

from .views import CustomRegisterView

urlpatterns = [
    path("auth/register/", CustomRegisterView.as_view(), name="custom_register"),
]
Вернуться на верх