Files
tripwithbonus/backend/api/auth/views.py
2025-05-18 13:37:27 +03:00

171 lines
6.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
import traceback
from django.contrib.auth.models import User
from django.conf import settings
from django.db.utils import IntegrityError
from django.db import IntegrityError, transaction
from .serializers import ClientRegisterSerializer, UserResponseSerializer
from api.utils.cookiesSet import AuthBaseViewSet
from datetime import datetime
class RegisterViewSet(AuthBaseViewSet):
"""Регистрация клиента"""
@action(detail=False, methods=['post'], url_path="clients")
def register_client(self, request):
serializer = ClientRegisterSerializer(data=request.data)
if serializer.is_valid():
try:
with transaction.atomic():
user = serializer.save()
refresh = RefreshToken.for_user(user)
user_data = UserResponseSerializer(user).data
response = Response(
{
"access": str(refresh.access_token),
"refresh": str(refresh),
"user": user_data
},
status=status.HTTP_201_CREATED
)
# используем метод из базового класса вместо прямой установки куки
return self._set_auth_cookies(response, refresh)
except IntegrityError as e:
return Response(
{"error": "Пользователь с таким email уже существует"},
status=status.HTTP_400_BAD_REQUEST
)
except Exception as e:
return Response(
{"error": str(e)},
status=status.HTTP_400_BAD_REQUEST
)
# ошибка валидации
return Response(
{
"error": "Ошибка валидации",
"details": serializer.errors
},
status=status.HTTP_400_BAD_REQUEST
)
class LoginViewSet(AuthBaseViewSet):
"""Логин для клиента"""
@action(detail=False, methods=['post'], url_path="clients")
def login_client(self, request):
try:
email = request.data.get("email")
password = request.data.get("password")
if not email or not password:
return Response(
{"error": "Email и пароль обязательны"},
status=status.HTTP_400_BAD_REQUEST
)
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
return Response(
{"error": "Пользователь не найден"},
status=status.HTTP_404_NOT_FOUND
)
if not user.check_password(password):
return Response(
{"error": "Неверный пароль"},
status=status.HTTP_403_FORBIDDEN
)
refresh = RefreshToken.for_user(user)
user_data = UserResponseSerializer(user).data
user_data["userType"] = "client"
response = Response({
"message": "Успешная авторизация",
"access": str(refresh.access_token),
"refresh": str(refresh),
"user": user_data
}, status=status.HTTP_200_OK)
# аналогично используем метод из базового класса
return self._set_auth_cookies(response, refresh)
except Exception as e:
return Response(
{"error": "Ошибка авторизации"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
class LogoutView(APIView):
"""Логаут"""
def post(self, request):
response = Response({'message': 'Logged out'}, status=status.HTTP_200_OK)
# чистим куки и sessionID
response.delete_cookie('access_token')
response.delete_cookie('refresh_token')
response.delete_cookie('sessionid')
return response
class RefreshTokenView(APIView):
def post(self, request):
try:
refresh_token = request.data.get('refresh')
if not refresh_token:
return Response(
{'error': 'Refresh token is required'},
status=status.HTTP_400_BAD_REQUEST
)
try:
token = RefreshToken(refresh_token)
# Сохраняем user_type при обновлении токена
if 'user_type' in token:
token.access_token['user_type'] = token['user_type']
# Добавляем точное время истечения токена
expires_at = datetime.now() + settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME']
response_data = {
'access': str(token.access_token),
'refresh': str(token),
'expires_at': datetime.timestamp(expires_at)
}
return Response(response_data)
except Exception as e:
# Более подробное логирование ошибок
print(f"Token refresh error: {str(e)}")
print(traceback.format_exc())
return Response(
{'error': f'Invalid refresh token: {str(e)}'},
status=status.HTTP_400_BAD_REQUEST
)
except Exception as e:
return Response(
{'error': f'Token refresh failed: {str(e)}'},
status=status.HTTP_400_BAD_REQUEST
)