最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

【快播报】DRF的权限组件(源码分析)

来源:博客园


(资料图)

DRF的权限组件(源码分析)

1. 创建用户表

from django.db import models# Create your models here.class UserInfo(models.Model):    role_choice = ((1, "CEO"), (2, "CTO"), (3, "CFO"))    role = models.SmallIntegerField(verbose_name="类型", choices=role_choice, default=1)    username = models.CharField(verbose_name="用户名", max_length=32)    password = models.CharField(verbose_name="密码", max_length=32)    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)

2. 自定义权限类

from rest_framework.permissions import BasePermissionclass PermissionA(BasePermission):    message = {"code": 1003, "data": "无权访问"}    def has_permission(self, request, view):        if request.user.role == 2:            return True        return False    def has_object_permission(self, request, view, obj):        return True

3. 视图函数中添加认证

  • 局部配置(views.py)
class UserView(APIView):    permission_classes = [PermissionA, ]  # role权限        def get(self, request):        ...
  • 全局配置(settings.py)
REST_FRAMEWORK = {    # 权限    "DEFAULT_PERMISSION_CLASSES": ["app01.permission.PermissionA", ]}

4. 多个权限类

当开发过程中需要用户同时具备多个权限(缺一不可)时,可以用多个权限类来实现。

权限组件内部处理机制:按照列表的顺序逐一执行 has_permission方法,如果返回True,则继续执行后续的权限类;如果返回None或False,则抛出权限异常并停止后续权限类的执行。

# models.pyfrom django.db import modelsclass Role(models.Model):    """ 角色表 """    title = models.CharField(verbose_name="名称", max_length=32)class UserInfo(models.Model):    """ 用户表 """    username = models.CharField(verbose_name="用户名", max_length=32)    password = models.CharField(verbose_name="密码", max_length=64)    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)    roles = models.ManyToManyField(verbose_name="角色", to="Role")
# urls.pyfrom django.urls import path, re_path, includefrom app01 import viewsurlpatterns = [    path("api/auth/", views.AuthView.as_view()),    path("api/order/", views.OrderView.as_view()),]
# views.pyimport uuidfrom rest_framework.views import APIViewfrom rest_framework.request import Requestfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.permissions import BasePermissionfrom rest_framework.exceptions import AuthenticationFailedfrom app01 import modelsclass AuthView(APIView):    """ 用户登录认证 """    def post(self, request, *args, **kwargs):        print(request.data)  # {"username": "wupeiqi", "password": "123"}        username = request.data.get("username")        password = request.data.get("password")        user_object = models.UserInfo.objects.filter(username=username, password=password).first()        if not user_object:            return Response({"code": 1000, "data": "用户名或密码错误"})        token = str(uuid.uuid4())        user_object.token = token        user_object.save()        return Response({"code": 0, "data": {"token": token, "name": username}})class TokenAuthentication(BaseAuthentication):    def authenticate(self, request):        token = request.query_params.get("token")        if not token:            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})        user_object = models.UserInfo.objects.filter(token=token).first()        if not user_object:            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})        return user_object, token    def authenticate_header(self, request):        return "Bearer realm="API""class PermissionA(BasePermission):    message = {"code": 1003, "data": "无权访问"}    def has_permission(self, request, view):        exists = request.user.roles.filter(title="员工").exists()        if exists:            return True        return False    def has_object_permission(self, request, view, obj):        return Trueclass PermissionB(BasePermission):    message = {"code": 1003, "data": "无权访问"}    def has_permission(self, request, view):        exists = request.user.roles.filter(title="主管").exists()        if exists:            return True        return False    def has_object_permission(self, request, view, obj):        return Trueclass OrderView(APIView):    authentication_classes = [TokenAuthentication, ]    permission_classes = [PermissionA, PermissionA]    def get(self, request, *args, **kwargs):        return Response({"code": 0, "data": {"user": None, "list": [1, 2, 3]}})class PayView(APIView):    authentication_classes = [TokenAuthentication, ]    permission_classes = [PermissionA, ]    def get(self, request, *args, **kwargs):        return Response({"code": 0, "data": "数据..."})

5. 关于has_object_permission

后期补充...

6. 源码分析

第三步前面的部分执行流程和前两篇文章是一样的. 这里就不过多赘述了

关键词: