Django DRF权限组件

在Django的drf框架内的权限组件,如果遇到多个权限认证类,是需要所有的权限类都要通过验证,才能访问视图。

一、简单示例

1、per.py 自定义权限类

python 复制代码
from rest_framework.permissions import BasePermission
import random

class MyPerssion(BasePermission):
    # 自定义一个类变量,处理错误信息的处理
    # 权限校验失败,会来这里找返回信息;
    message = {"status":False,"msg":"无权访问"}

    # 模拟验证
    def has_permission(self, request, view):
        #获取请求中的数据,然后进行校验
        v1 = random.randint(1,3)
        if v1 == 2:
            return True
        else:
            return

2、views.py

python 复制代码
class UserView(APIView):
    permission_classes = [MyPerssion,]
    def get(self,request):
        print(request.user,request.auth)
        return Response("UserView")

3、settings.py ,如果需要全局设置,可以如下设置

python 复制代码
REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    "UNAUTHENTICATED_TOKEN": None,

     自定义权限组件的全局配置
     "DEFAULT_PERMISSION_CLASSES":[
         'ext.per.MyPerssion',
     ]
}

二、如果存在多个认证类的情况下,实现部分认证类通过即可通过验证,就需要重写has_perssion方法,示例如下:

1、per.py ,自定义权限类,下面模拟定义了3个权限类

python 复制代码
'''自定义权限类'''
from rest_framework.permissions import BasePermission

class MyPermission1(BasePermission):
    # 自定义一个类变量,处理错误信息的处理
    # 权限校验失败,会这里来返回错误信息;
    message = {"status":False,"msg":"无权访问1"}

    def has_permission(self, request, view):
        print("MyPermission1")
        return False

class MyPermission2(BasePermission):
    message = {"status": False, "msg": "无权访问2"}
    def has_permission(self, request, view):
        print("MyPermission2")
        return False

class MyPermission3(BasePermission):
    message = {"status": False, "msg": "无权访问3"}
    def has_permission(self, request, view):
        print("MyPermission3")
        return False

2、 view.py 自定义NbApiView,继承APIView,重写check_permission方法,实现多个权限类认证的关系,改为或的关系。

python 复制代码
'''使得权限类认证之间关系是或的关系,自定义'''

from rest_framework.views import APIView

# 满足任意条件即可,A条件、B条件、C条件
class NbApiView(APIView):

    def check_permissions(self, request):
        # 定义一个错误列表,最后去列表中的第一个错误信息
        no_permission_object = []
        for permission in self.get_permissions():
            if permission.has_permission(request,self):
                return
            else:
                no_permission_object.append(permission)
        else:
            self.permission_denied(request,
                                   message=getattr(no_permission_object[0],'message',None),
                                   code=getattr(no_permission_object[0],'code',None))

3、views.py

python 复制代码
from ext.view import NbApiView
class OrderView(NbApiView):
    permission_classes = [MyPermission1,MyPermission2,MyPermission3,]

    def get(self,request):

        return Response({"status":True,"data":[11,22,33,44]})

三、案例应用

有老板(boss)、经理(manager)、员工(user)三个角色, 有三个视图,分别有不同权限的人可以访问,实现方法如下:

1、models.py

python 复制代码
class UserInfo(models.Model):
    '''用户表'''

    role = models.IntegerField(verbose_name="角色",choices=((1,"总监"),(2,"经理"),(3,"员工")),default=3)

    username = models.CharField(verbose_name="用户名",max_length=32)
    password = models.CharField(verbose_name="密码",max_length=64)
    # 临时测试方法,token可以存放到很多地方,例如radis jwt等
    token = models.CharField(verbose_name="TOKEN",max_length=64,null=True,blank=True)

2、urls.py

python 复制代码
urlpatterns = [
    path('login/', views.LoginView.as_view()),
    path('user/', views.UserView.as_view()),
    path('order/', views.OrderView.as_view()),
    path('avatar/', views.AvatarView.as_view()),
]

3、per.py

python 复制代码
# 员工权限认证
class UserPermission(BasePermission):
    message = {"status":False,"msg":"无权访问"}

    def has_permission(self, request, view):
        if request.user.role == 3:
            return True
        else:
            return False

# 经理权限认证
class ManagerPermission(BasePermission):
    message = {"status": False, "msg": "无权访问"}
    def has_permission(self, request, view):
        if request.user.role == 2:
            return True
        else:
            return False

# 老板权限认证
class BossPermission(BasePermission):
    message = {"status": False, "msg": "无权访问"}
    def has_permission(self, request, view):
        if request.user.role == 1:
            return True
        else:
            return False

4、view.py

python 复制代码
from rest_framework.views import APIView

# 满足任意条件即可,A条件、B条件、C条件
class NbApiView(APIView):

    def check_permissions(self, request):
        # 定义一个错误列表,最后去列表中的第一个错误信息
        no_permission_object = []
        for permission in self.get_permissions():
            if permission.has_permission(request,self):
                return
            else:
                no_permission_object.append(permission)
        else:
            self.permission_denied(request,
                                   message=getattr(no_permission_object[0],'message',None),
                                   code=getattr(no_permission_object[0],'code',None))

5、views.py

python 复制代码
class UserView(NbApiView):
    # 经理、老板、员工都可以访问
    permission_classes = [UserPermission,ManagerPermission,BossPermission]
    def get(self,request):
        return Response({"status":True,"data":[11,22,33,44]})

class OrderView(NbApiView):
    # 经理或者老板可以访问
    permission_classes = [ManagerPermission,BossPermission]

    def get(self,request):
        return Response({"status":True,"data":[11,22,33,44]})

class AvatarView(NbApiView):
    # 老板或者员工可以访问
    permission_classes = [UserPermission,BossPermission]

    def get(self,request):
        return Response({"status":True,"data":[11,22,33,44]})
相关推荐
好家伙VCC1 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
orange_tt2 小时前
Djiango配置Celery
数据库·sqlite
前端玖耀里3 小时前
如何使用python的boto库和SES发送电子邮件?
python
serve the people3 小时前
python环境搭建 (十二) pydantic和pydantic-settings类型验证与解析
java·网络·python
小天源3 小时前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
喵手3 小时前
Python爬虫实战:HTTP缓存系统深度实战 — ETag、Last-Modified与requests-cache完全指南(附SQLite持久化存储)!
爬虫·python·爬虫实战·http缓存·etag·零基础python爬虫教学·requests-cache
喵手3 小时前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度
2601_949146534 小时前
Python语音通知接口接入教程:开发者快速集成AI语音API的脚本实现
人工智能·python·语音识别
寻梦csdn4 小时前
pycharm+miniconda兼容问题
ide·python·pycharm·conda
Java面试题总结5 小时前
基于 Java 的 PDF 文本水印实现方案(iText7 示例)
java·python·pdf