login route
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
from rest_framework.views import APIView
|
||||
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .serializers import (
|
||||
UserResponseSerializer,
|
||||
LoginRequestSerializer,
|
||||
LoginResponseSerializer
|
||||
)
|
||||
|
||||
from api.utils.cookies import AuthBaseViewSet
|
||||
from api.types import User
|
||||
|
||||
|
||||
class LoginViewSet(AuthBaseViewSet):
|
||||
"""ViewSet для авторизации пользователей"""
|
||||
serializer_class = LoginRequestSerializer
|
||||
|
||||
@extend_schema(
|
||||
summary="Авторизация пользователя",
|
||||
description="Эндпоинт для авторизации пользователя по логину и паролю",
|
||||
request=LoginRequestSerializer,
|
||||
responses={
|
||||
200: OpenApiResponse(
|
||||
response=LoginResponseSerializer,
|
||||
description="Успешная авторизация",
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Успешный ответ',
|
||||
value={
|
||||
"message": "Успешная авторизация",
|
||||
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
||||
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"email": "user@example.com",
|
||||
"account_type": "engieneer",
|
||||
"name": "Иван",
|
||||
"surname": "Иванов",
|
||||
"imageURL": "https://example.com/avatar.jpg",
|
||||
"uuid": "abc123"
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
),
|
||||
400: OpenApiResponse(
|
||||
description="Неверные параметры запроса",
|
||||
response=OpenApiTypes.OBJECT,
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Отсутствуют обязательные поля',
|
||||
value={"error": "Логин и пароль обязательны"}
|
||||
)
|
||||
]
|
||||
),
|
||||
403: OpenApiResponse(
|
||||
description="Неверный пароль",
|
||||
response=OpenApiTypes.OBJECT,
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Неверный пароль',
|
||||
value={"error": "Неверный пароль"}
|
||||
)
|
||||
]
|
||||
),
|
||||
404: OpenApiResponse(
|
||||
description="Пользователь не найден",
|
||||
response=OpenApiTypes.OBJECT,
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Пользователь не найден',
|
||||
value={"error": "Пользователь не найден"}
|
||||
)
|
||||
]
|
||||
),
|
||||
500: OpenApiResponse(
|
||||
description="Внутренняя ошибка сервера",
|
||||
response=OpenApiTypes.OBJECT,
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Ошибка сервера',
|
||||
value={"error": "Ошибка авторизации"}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
)
|
||||
@action(detail=False, methods=['post'], url_path="login")
|
||||
def login_client(self, request):
|
||||
try:
|
||||
login = request.data.get("login")
|
||||
password = request.data.get("password")
|
||||
|
||||
if not login or not password:
|
||||
return Response(
|
||||
{"error": "Логин и пароль обязательны"},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
try:
|
||||
user = User.objects.get(login=login)
|
||||
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
|
||||
|
||||
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):
|
||||
"""ViewSet для выхода из системы"""
|
||||
|
||||
@extend_schema(
|
||||
summary="Выход из системы",
|
||||
description="Эндпоинт для выхода из системы, очищает все токены и куки",
|
||||
responses={
|
||||
200: OpenApiResponse(
|
||||
description="Успешный выход",
|
||||
response=OpenApiTypes.OBJECT,
|
||||
examples=[
|
||||
OpenApiExample(
|
||||
'Успешный выход',
|
||||
value={"message": "Logged out"}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
)
|
||||
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
|
||||
Reference in New Issue
Block a user