Токен обновления передается в теле ответа при регистрации, но не для входа в систему в 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"),
]