Django REST框架中的多角色用户身份验证
#python #django #djangorestframework #multiroleuserauthentication

介绍:

用户身份验证是许多Web应用程序的基本方面。 Django提供了强大的身份验证系统,但有时您需要将其扩展以支持多个用户角色。在这篇文章中,我们将探讨如何使用DJANGO REST框架(DRF)实现多运行用户身份验证。

设置项目:

让我们从创建一个新的Django项目开始。如果您没有设置Django环境,则可以按照以下步骤创建一个:

  1. 创建一个虚拟环境:python -m venv venv
  2. 激活虚拟环境:venv\Scripts\activate

激活环境后,安装django和django rest框架:

pip install django djangorestframework

您可以遵循您喜欢的任何方法来设置环境。当您的Env准备就绪时,请打开终端(带有ENV激活)并运行以下命令:

django-admin startproject multi_role_auth
cd multi_role_auth

启动我们的authentication应用程序:

开放终端(带有ENV激活)并运行以下命令:

python manage.py startapp authentication

现在我们已经准备好了项目结构,让我们深入研究实施。

定义用户模型:

authentication/models.py文件中,我们将定义一个自定义用户模型,该模型从Django的身份验证模型中扩展了Abstractuser类。该模型将包括一个role字段,以分配每个用户的角色。

# authentication/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
from rest_framework.authtoken.models import Token


class User(AbstractUser):
    ROLE_CHOICES = (
        ('administrator', 'Administrator'),
        ('teacher', 'Teacher'),
        ('student', 'Student'),
        ('staff', 'Staff'),
    )

    role = models.CharField(max_length=15, choices=ROLE_CHOICES)

随意自定义ROLE_CHOICES元组,以包括与您的应用程序相关的特定角色。此外,如果您需要更多的用户模型字段,则可以轻松地将其添加到此模型中。您可以参考documentation来探索Django用户模型提供的所有默认字段。这种灵活性使您可以量身定制用户模型满足项目的特定要求。

创建连续剧器:

接下来,为我们的身份验证应用程序创建串行化。连续化器有助于将复杂的数据类型转换为JSON,从而轻松地通过HTTP发送数据。

创建authentication/serializers.py并添加以下代码:

# authentication/serializers.py

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'email', 'role', 'password']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user

在这里,我们定义了一个从DRF提供的ModelSerializer继承的UserSerializer。我们将模型指定为我们的自定义用户模型,并定义要在序列化表示中包含的字段。此外,我们将“密码”字段设置为仅写入,以防止其在响应中暴露。在fields属性中,您可以通过传递fields = '__all__'包含所有字段。

创建视图:

现在,让我们实现用户注册,登录和注销的视图。

authentication/views.py中,添加以下代码:

# authentication/views.py

from authentication.models import User
from authentication.serializers import UserSerializer
from django.contrib.auth import authenticate, login
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.permissions import IsAuthenticated


class UserRegistrationView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)



class UserLoginView(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        username = request.data.get('username')
        password = request.data.get('password')

        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            token, created = Token.objects.get_or_create(user=user)
            if created:
                token.delete()  # Delete the token if it was already created
                token = Token.objects.create(user=user)
            return Response({'token': token.key, 'username': user.username, 'role': user.role})
        else:
            return Response({'message': 'Invalid username or password'}, status=status.HTTP_401_UNAUTHORIZED)



class UserLogoutView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        print(request.headers) 
        token_key = request.auth.key
        token = Token.objects.get(key=token_key)
        token.delete()

        return Response({'detail': 'Successfully logged out.'})

UserRegistrationView中,我们处理HTTP POST请求以进行用户注册。我们使用UserSerializer验证数据并在用户有效时保存数据。

UserLoginView中,我们处理用户登录功能。我们使用提供的用户名和密码对用户进行身份验证,如果成功的话,使用DRF的令牌模型生成令牌。我们返回令牌以及用户名和响应中的角色。

UserLogoutView负责记录身份验证的用户。它从请求的身份验证标头中检索令牌,如果存在,则删除令牌,并返回成功消息。

更新URL:

最后,我们需要为我们的身份验证应用程序定义URL。

multi_role_auth/urls.py中,添加以下代码:

# multi_role_auth/urls.py

from django.urls import path, include
from authentication.views import UserRegistrationView, UserLoginView, UserLogoutView

urlpatterns = [
    path('api/auth/register/', UserRegistrationView.as_view(), name='user-registration'),
    path('api/auth/login/', UserLoginView.as_view(), name='user-login'),
    path('api/auth/logout/', UserLogoutView.as_view(), name='user-logout'),
    # Add other URLs here
]

在这里,我们映射
/api/auth/register/ url到UserRegistrationView
venv\Scripts\activate url到UserLoginView
api/auth/logout/ url到UserLogoutView

修改settings.py

要在DRF中启用基于令牌的身份验证,我们需要对设置进行一些修改。

在“ Multi_role_auth/settings.py”中,添加或更新以下设置:

# multi_role_auth/settings.py

# ...

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'rest_framework.authtoken',
    'authentication',
]

# ...

AUTH_USER_MODEL = 'authentication.User'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

在这里,我们将rest_frameworkauthentication添加到INSTALLED_APPS列表中,以包括必要的软件包。此外,我们已经配置了DEFAULT_AUTHENTICATION_CLASSESTokenAuthentication类用于基于令牌的身份验证。

记住在测试应用程序之前运行迁移:

python manage.py makemigrations
python manage.py migrate

测试:

在这里,我使用Postman

测试了authentication端点

注册用户:
将邮政请求发送到http://localhost:8000/api/auth/register/,并在请求正文中使用以下有效载荷:

{
  "username": "johndoe",
  "email": "johndoe@example.com",
  "password": "$tr0ngPa$$w0rd",
  "role": "student"
}

Register a user by using postman

登录:
将邮政请求发送到http://localhost:8000/api/auth/login/,并在请求正文中使用以下有效载荷:

{
  "username": "johndoe",
  "password": "$tr0ngPa$$w0rd"
}

Login by using postman

注销:
将邮政请求发送给http://localhost:8000/api/auth/logout/,并在请求标题中带有令牌。将带有值Token {token}Authorization标头包含(替换{token},用登录过程中获得的实际令牌值)。
Logout by using postman

结论:

在本教程中,我们介绍了使用DJANGO REST框架实现多角色用户身份验证的过程。我们定义了一个自定义用户模型,创建了用于用户注册和登录的序列化器,实现了用户注册,登录和注销的视图,并更新了项目的URL和设置以支持基于令牌的身份验证。

通过扩展Django的内置用户模型并利用Django Rest框架的功能,您可以轻松地将基于角色的身份验证添加到Django应用程序中。这使您可以根据用户的角色区分用户权限并提供量身定制的体验。

根据您的应用程序要求,请随时探索并添加其他功能,例如密码重置和基于角色的访问控制(RBAC)。

快乐编码!