Как реализовать систему входа без использования аутентификации по умолчанию в 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)