register logic

This commit is contained in:
2025-05-18 13:37:27 +03:00
parent be46e09aeb
commit 695c29ab62
19 changed files with 498 additions and 36 deletions

View File

@@ -1,6 +1,171 @@
from rest_framework import serializers
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.contrib.auth.hashers import make_password
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
)