from dmr.controller import Controller
from dmr.components import Body, Cookie, ResponseContext
from django.http import JsonResponse
from .schemas import (
LoginRequestSchema, LoginResponseSchema,
RefreshResponseSchema, LogoutResponseSchema
)
from .services import AuthService
class AuthController(Controller):
"""Контроллер управления сессиями и JWT-токенами."""
async def post_login(
self,
# Компонент Body автоматически парсит и валидирует входящий JSON
body: Body[LoginRequestSchema],
# Контекст для работы с заголовками ответа и Set-Cookie
ctx: ResponseContext,
) -> LoginResponseSchema:
"""Аутентификация пользователя и выдача пары токенов."""
# Достаем провалидированные данные
payload = body.value
user = await AuthService.authenticate_user(email=payload.email, password=payload.password)
access_token = await AuthService.generate_access_token(user)
refresh_token = await AuthService.generate_refresh_token(user)
# Устанавливаем куку через контекст ответа django-modern-rest
ctx.set_cookie(
key="refresh",
value=refresh_token,
httponly=True,
secure=True,
samesite="Lax",
path="/api/v1/auth/refresh/",
max_age=604800
)
# Возвращаем объект схемы (библиотека сама сериализует его)
return LoginResponseSchema(access=access_token)
async def post_refresh(
self,
# Компонент Cookie автоматически извлекает refresh из кук запроса
refresh_cookie: Cookie[str, "refresh"],
) -> RefreshResponseSchema:
"""Обновление сессии по Refresh-токену из куки."""
try:
new_access_token = await AuthService.refresh_session(refresh_cookie.value)
return RefreshResponseSchema(access=new_access_token)
except AuthService.InvalidTokenError:
# Превращается в валидный 401 ответ через встроенный обработчик ошибок DMR
return JsonResponse({"detail": "Invalid or expired refresh token"}, status=401)
async def post_logout(self, ctx: ResponseContext) -> LogoutResponseSchema:
"""Выход из системы с затиранием авторизационной куки."""
ctx.set_cookie(
key="refresh",
value="",
httponly=True,
secure=True,
samesite="Lax",
path="/api/v1/auth/refresh/",
max_age=0
)
return LogoutResponseSchema(detail="Successfully logged out.")