DRF-Permission组件源码分析及改编源码
1. 权限组件源码分析
PS:下列源码为了方便理解都进行了简化,只保留了权限相关的代码



由于视图函数中继承了APIView,因此permission_classes可在视图类中进行重写。
注意点:
- 执行权限校验前,已执行了认证流程。因此此时可通过self.user获取用户对象(认证通过的情况)

2. 实践:编写一个权限类
假设我们在认证通过后,给每个用户对象都加上表示角色的属性role。1代表普通用户, 2代表经理, 3代表BOSS:
import random
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
class UserPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 3:
return True
return False
class ManagerPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 2:
return True
return False
class BossPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 1:
return True
return False
3. 源码改编
- 将权限校验中的“且”改为“或”关系,即只要有一个权限类通过校验即代表权限校验通过,继续执行后续代码:
# 在视图类中重写源码中的check_permissions方法:
def check_permissions(self, request):
no_permission_objects = [] # 未通过校验的权限对象
for permission in self.get_permissions():
if permission.has_permission(request, self):
# 只要有一个权限类通过校验则立即停止函数
return
else:
no_permission_objects.append(permission)
else: # 所有权限类都未通过校验
self.permission_denied(
request,
message=getattr(no_permission_objects[0], 'message', None),
code=getattr(no_permission_objects[0], 'code', None))
- 若想要所有视图类能使用该重写的功能,可将该方法单独写成类(MyAPIView),并继承APIView;其他要使用该重写方法的视图不再继承APIView,而是继承MyAPIView
# utils.py
class MyAPIView(APIView):
# 改写权限,变为"或"关系;
def check_permissions(self, request):
no_permission_objects = [] # 未通过校验的权限对象
for permission in self.get_permissions():
if permission.has_permission(request, self):
# 只要有一个权限类通过校验则立即停止函数
return
else:
no_permission_objects.append(permission)
else: # 所有权限类都未通过校验
self.permission_denied(
request,
message=getattr(no_permission_objects[0], 'message', None),
code=getattr(no_permission_objects[0], 'code', None))
# views.py
class UserView(APIView): # 继承DRF的APIView,则权限判断为“且”的关系
# 只有用户有权限
permission_classes = [UserPermission]
def get(self, request, pid):
return Response("hello get")
def post(self, request, pid):
return Response({"nihao post!"})
class OrderView(MyAPIView): # 用了自己改写的类MyAPIView,则权限判断为“或"的关系
# 经理和BOSS都有权限
permission_classes = [BossPermission, ManagerPermission]
def get(self, request, pid):
return Response("hello get")
def post(self, request, pid):
return Response({"nihao post!"})
DRF-Permission组件源码分析及改编源码的更多相关文章
- drf的基本使用、APIView源码分析和CBV源码拓展
cbv源码拓展 扩展,如果我在Book视图类中重写dispatch方法 -可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果 def dispatch(self, requ ...
- NIO 源码分析(05) Channel 源码分析
目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...
- NIO 源码分析(02-2) BIO 源码分析 Socket
目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...
- NIO 源码分析(02-1) BIO 源码分析
目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...
- [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast
[源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- k8s client-go源码分析 informer源码分析(3)-Reflector源码分析
k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...
- 5.2 spring5源码--spring AOP源码分析三---切面源码分析
一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...
- jQuery1.11源码分析(1)-----Sizzle源码概览[原创]
最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...
- 【MyBatis源码分析】select源码分析及小结
示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...
随机推荐
- 手写一个AQS实现
1.背景 1.AQS简介AQS全称为AbstractQueuedSynchronizer(抽象队列同步器).AQS是一个用来构建锁和其他同步组件的基础框架,使用AQS可以简单且高效地构造出应用广泛的同 ...
- Flutter&Dart Callback转同步
前言 怎么将一个Callback回调转化成Future同步方法(Callback to Future),可以配套async / await去使用呢? 个人觉得,这是一个很常见的现象,不知道为啥,很多人 ...
- ibatis执行存储过程,java.lang.ArrayIndexOutOfBoundsException: 0
在项目开发中遇到一个问题,ibatis执行存储过程时报错 <procedure id="insertStatisticsResult_settle" parameterCla ...
- 禅道项目管理系统权限绕过漏洞(QVD-2024-15263)
本文所涉及的任何技术.信息或工具,仅供学习和参考之用,请勿将文章内的相关技术用于非法目的,如有相关非法行为与文章作者无关.请遵守<中华人民共和国网络安全法>. 1. 概述 1.1 基本信息 ...
- 使用Istio服务网格进行微服务网络治理
在Rainbond中,用户可以对不同的应用设置不同的治理模式,即用户可以通过切换应用的治理模式,来按需治理应用,这样带来的好处便是用户可以不被某一个ServiceMesh框架所绑定,且可以快速试错,能 ...
- 零基础学习人工智能—Python—Pytorch学习(八)
前言 本文介绍卷积神经网络的上半部分. 其实,学习还是需要老师的,因为我自己写文章的时候,就会想当然,比如下面的滑动窗口,我就会想当然的认为所有人都能理解,而实际上,我们在学习的过程中之所以卡顿的点多 ...
- Windows提权方式汇总
windows 提权 一.土豆(potato)家族提权 原理 土豆提权就是通过 windows 的 COM(Component Object Model,组件对象模型)类.向指定的服务器端口发送 NT ...
- PowerShell 使用
Practice 常用命令 vim $PROFILE # 编辑配置文件 Get-ChildItem *> $null # 抛弃所有输出 whoami Remove-Item -Recurse - ...
- diff 输出解释
diff 最原始的 diff 我们先编写两个文件: f1: 1 2 3 4 5 6 7 8 9 f2: 1 2 3 4 5 66 7 8 9 然后我们进行比较: diff f1 f2 6c6 < ...
- WKCTF RE
WKCTF so_easy 安卓逆向,关键的check逻辑都在native层里面 主要是很多层的异或操作 除了Z3和爆破想不到其他方法了 from z3 import * src = [ 0xAE, ...