简体   繁体   English

如何在不使用 Python/Django 中的 django 默认身份验证的情况下实现登录系统?

[英]How can I implement a Login system without using django default authentication in Python/Django?

Suppose I have a self-made User Model which holds username and password field.假设我有一个自制的用户 Model,其中包含用户名和密码字段。 Now I want to login with my self-made username and password in Django.现在我想在 Django 中使用我自制的用户名和密码登录。 How can I do that?我怎样才能做到这一点? Besides I need to build a Login Api using this username and password.此外,我需要使用这个用户名和密码建立一个登录 Api。 How to do that?怎么做?

I can implement the simple login system like the following.我可以像下面这样实现简单的登录系统。

TokenAuthentication can be used in the DRF by adding some configs in settings.py file.通过在settings.py文件中添加一些配置,可以在 DRF 中使用TokenAuthentication

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

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

Now create the users app by executing the following command.现在通过执行以下命令创建users应用程序。

python manage.py startapp users

And I can create the custom user model in the models.py.我可以在 models.py 中创建自定义用户 model。 Let's say that the app name is "users" and the model name is "Account".假设应用名称为“users”,model 名称为“Account”。 You need to set the AUTH_USER_MODEL in settings.py.您需要在 settings.py 中设置AUTH_USER_MODEL

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

# specify user model
AUTH_USER_MODEL = 'users.Account'

In models.py of the users app, I can define the user model by deriving from the AbstractBaseUser .users应用程序的 models.py 中,我可以通过从AbstractBaseUser派生来定义用户 model 。

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)

In serializers.py, you can set the password field as write-only.在 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}
        }

Finally, in urls.py of the users app, login can be implemented using rest_framework.authtoken最后,在users应用的 urls.py 中,可以使用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")
]

Of course, you can also implement the user register in views.py.当然也可以在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM