Как реализовать систему входа без использования аутентификации по умолчанию в Python/Django?

Предположим, у меня есть самодельная модель пользователя, которая содержит поле имени пользователя и пароля. Теперь я хочу войти в Django с моим самодельным именем пользователя и паролем. Как я могу это сделать? Кроме того, мне нужно создать Login Api, использующий эти имя пользователя и пароль. Как это сделать?

Я могу реализовать простую систему входа в систему следующим образом.

TokenAuthentication можно использовать в DRF, добавив некоторые конфигурации в файл settings.py.

# REST framework
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication'
    ]
}

Теперь создайте приложение users, выполнив следующую команду.

python manage.py startapp users

И я могу создать пользовательскую модель пользователя в models.py. Предположим, что имя приложения - "users", а имя модели - "Account". Вам нужно установить AUTH_USER_MODEL в settings.py.

# Application definition
INSTALLED_APPS = [
    ...
    'rest_framework',
    'corsheaders',
    'users',
    'rest_framework.authtoken'
]

# specify user model
AUTH_USER_MODEL = 'users.Account'

В models.py приложения users я могу определить модель пользователя, производя ее от модели AbstractBaseUser.

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, UserManager
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token


class Account(AbstractBaseUser):
    """
    A model for users

    It simply has the three fields `username`, `password`, `last_login`.
    In addition, it has several shifts.
    """
    username = models.CharField(max_length=50, unique=True)

    USERNAME_FIELD = 'username'
    objects = UserManager()


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

В файле serializers.py можно установить поле password как доступное только для записи.

from attr import fields
from rest_framework import serializers    
from .models import Account
    
class AccountSerializer(serializers.ModelSerializer):   
    class Meta:
        fields = '__all__'
        model = Account
        extra_kwargs = {
            'password': {'write_only': True}
        }

Наконец, в urls.py приложения users логин может быть реализован с помощью rest_framework.authtoken

from django.urls import path
from rest_framework.authtoken import views
from .views import AccountView

urlpatterns = [
    path('login', views.obtain_auth_token, name="login"),
    path('register', AccountView.as_view(), name="register")
]

Конечно, вы также можете реализовать регистрацию пользователя в файле views.py.

from django.shortcuts import render
from rest_framework.generics import CreateAPIView

from users.serializers import AccountSerializer
from .models import Account
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status

class AccountView(CreateAPIView):
    queryset = Account.objects.all()
    serializer_class = AccountSerializer
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            input_data = serializer.validated_data
            username = input_data.get('username')
            password = input_data.get('password')

            # create user and set password
            user = Account.objects.create(username=username)
            user.set_password(password)
            user.save()
            return Response(AccountSerializer(user).data, status=status.HTTP_201_CREATED)

        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Вернуться на верх