Представления входа и выхода из системы 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'),