Представления входа и выхода из системы Django REST Framework

Я строю

систему, используя django, django rest framework, django oauth toolkit, django axes в архитектуре микросервисов, но у меня есть некоторые сомнения. Сейчас у меня есть представление "login" на клиенте, которое принимает имя пользователя и пароль из POST-запроса и отправляет их в API "UserLoginAPI", в представлении "UserLoginApi" я проверяю пользователя и пароль в сериализаторе "UserLoginSerializer", проверяю, не заблокирован ли пользователь в django axes и создаю токен для этого пользователя с помощью oauth, сериализатор возвращает аутентифицированного пользователя и токен, а "UserLoginApi" обновляет last_login с помощью update_last_login, Я видел в обсуждении на stackoverflow, что нужно использовать update_last_login вместо login(request, user), затем я возвращаю токен обратно в представление "login" на клиенте, а на клиенте я беру этот токен и храню его в сессии и с помощью middleware я проверяю в каждом запросе, существует ли токен, и если токен существует, если он уже истек, если он существует и не истек, я обновляю пользователя сессии с пользователем, связанным с токеном. При выходе из системы я делаю то же самое, но использую logout(request) для выхода пользователя из системы и посылаю сигнал в axes, чтобы узнать, что пользователь вышел из системы. Я хочу знать, правильна ли моя логика, созданная до сих пор, и правильно ли я создал систему аутентификации. Я также хотел бы знать, как я могу подтвердить только определенные представления с помощью моего промежуточного ПО, я хотел бы аутентифицировать только те представления, которые имеют декоратор @login_required для предварительной проверки.

Если вы можете указать, на правильном ли я пути или мне нужно что-то улучшить, я буду благодарен.

попробуйте и вы один раз

views.py

from .serializers import RegisterSerializer,LoginSerializer
from .models import Person

from django.contrib.auth import logout
from django.conf import settings
from django.core.mail import EmailMessage

from rest_framework import generics,status
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token


class RegisterAPIView(APIView):
    serializer_class = RegisterSerializer

    def post(self, request, format=None):
        serializer = RegisterSerializer(data=request.data)
        if not serializer.is_valid(raise_exception=True):
            return Response({"message":"serializer not valid"})
        serializer.save()
        return Response( {"message":"successfully register"}, status=status.HTTP_200_OK)


class LoginAPIView(APIView):
     serializer_class = LoginSerializer

     def post(self, request, format=None):
        serializer = LoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        user = serializer.validated_data.get("product_details")

        return Response({"message":"successfully login"}, status=status.HTTP_200_OK)


class logoutView(APIView):
    permission_classes=(AllowAny,)
    
    def post(self,request,*args,**kwargs):
        logout(request)
        return Response({"detail":"logout successfully"})

serializer.py

from  rest_framework import serializers
from .models import Person
from django.contrib.auth.password_validation import validate_password
from rest_framework.validators import UniqueValidator
from django.contrib.auth import authenticate
from rest_framework import exceptions
from django.conf import settings 
from django.core.mail import send_mail
from django.core.mail import EmailMessage
        

class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('username','firstname', 'lastname', 'phone', 'email', 'password', 'confirmpassword')
        extra_kwargs = {"firstname": {"required": True}, "lastname": {"required": True}}

    def validate(self, data):
        if len(data["phone"]) != 10:
            raise serializers.ValidationError({"phone": "phone number is not valid"})
        elif data["password"] != data["confirmpassword"]:
            raise serializers.ValidationError({"password": "Password fields didn't match."})
        return data

    def create(self, validated_data):
        
        person_details= Person.objects.create(**validated_data)
        person_details.save()
        return validated_data 

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)
   
    class Meta:
        model = Person
        fields = ['username', 'password']

    def validate(self, data):
        username = data.get('username')
        password = data.get('password')
        product_details = Person.objects.get(username=username, password=password)
        if not product_details:
            raise serializers.ValidationError("Invalid username or password")

        data['product_details'] = product_details
        return data
        
    
class logoutserializer(serializers.Serializer):
    user= serializers.CharField()

models.py

from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractUser


# Create your models here.
class Person(models.Model):
    username =models.CharField(max_length=100)
    firstname=models.CharField(max_length=100,default="")
    lastname=models.CharField(max_length=100,default="")
    phone = models.CharField(max_length=15)
    email=models.EmailField(unique=True)
    password=models.CharField(max_length=100)
    confirmpassword=models.CharField(max_length=100,default="")

    
    def _str_(self):
        return f"{self.username}{self.firstname}{self.lastname}{self.phone}{self.email}{self.password}{self.confirmpassword}"

urls.py

from django.contrib import admin
from django.urls import path
from .views import RegisterAPIView,LoginAPIView

urlpatterns = [
    path('register/', RegisterAPIView.as_view(), name='register'),
    path('login/', LoginAPIView.as_view(), name='register'),
    path('logout/',logoutView.as_view(),name='logout'),
Вернуться на верх