Django(63)drf权限源码分析与自定义权限
前言
上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf
默认是允许所有用户访问
权限源码分析
源码入口:APIView.py
文件下的initial
方法下的check_permissions
def check_permissions(self, request):
"""
检查是否应允许该请求。如果请求不被允许,则引发适当的异常。
"""
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
权限在get_permissions
方法中获取到,源码如下:
def get_permissions(self):
"""
实例化并返回此视图所需的权限列表。
"""
return [permission() for permission in self.permission_classes]
permission_classes
又等于api_settings.DEFAULT_PERMISSION_CLASSES
,所以我们去settings.py
文件中查找
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
我们会发现drf
默认的权限是AllowAny
,我们去看下源码:
class AllowAny(BasePermission):
"""
允许任意访问。这不是严格要求的,因为您可以使用空的 permission_classes 列表,但它很有用,因为它使意图更加明确。
"""
def has_permission(self, request, view):
return True
我们可以看到AllowAny
继承自BasePermission
,然后定义了has_permission
方法,返回值为True
。
drf为我们提供了4个系统权限认证:
1. AllowAny
认证规则全部返回True:`return True`
游客与登录用户都有所有权限
2. IsAuthenticated
认证规则必须有登录的合法用户:`return bool(request.user and request.user.is_authenticated)`
游客没有任何权限,登录用户才有权限
3. IsAdminUser
认证规则必须是:`return bool(request.user and request.user.is_staff)`
游客没有任何权限,登录用户才有权限
4. IsAuthenticatedOrReadOnly
认证规则必须是只读请求或者是合法用户无限制
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
游客只读,合法用户无限制
自定义认证类
- 创建继承
BasePermission
的权限类 - 实现
has_permission
方法 - 实现体根据权限规则 确定 有无权限
- 进行全局或局部配置(一般采用局部配置)
权限规则
满足设置的用户条件,代表有权限,返回True
不满足设置的用户条件,代表有权限,返回False
自定义权限
from django.contrib.auth.models import Group
from rest_framework.permissions import BasePermission
class MyPermissions(BasePermission):
def has_permission(self, request, view):
rule1 = request.method in ['GET', 'OPTIONS', 'HEAD']
group = Group.objects.filter(name="管理员").first()
groups = request.user.groups.all()
rule2 = group in groups
rule3 = group and groups
return rule1 or (rule2 and rule3)
以上定义了3条规则
- rule1:请求方法是
GET
、OPTIONS
、HEAD
游客和用户都可以访问 - rule2:当前用户如果有多个分组,其中必须有一个分组是管理员
- rule3:管理员分组必须存在,用户必须在分组中
接下里我们定义视图
class TestView(APIView):
permission_classes = [MyPermissions]
def get(self, request, *args, **kwargs):
print(request.user)
return APIResponse(data_msg="所有用户都可以访问")
def post(self, request, *args, **kwargs):
print(request.user)
return APIResponse(data_msg="只有管理员用户可以访问")
视图中只是添加了permission_classes = [MyPermissions]
属与局部配置,也就是自定义的权限只针对此视图,其他视图还是默认的全局配置,如果我们还有其他的关于权限的需求,只需要在自定义的权限类中写逻辑即可
Django(63)drf权限源码分析与自定义权限的更多相关文章
- Django-restframework 之权限源码分析
Django-restframework 之权限源码分析 一 前言 上篇博客分析了 restframework 框架的认证组件的执行了流程并自定义了认证类.这篇博客分析 restframework 的 ...
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 在前面的文章中我们曾经涉及到ControllerActionInvoker类GetPara ...
- Django(44)drf序列化源码分析(1)
序列化与反序列化 一般后端数据返回给前端的数据格式都是json格式,简单易懂,但是我们使用的语言本身并不是json格式,像我们使用的Python如果直接返回给前端,前端用的javascript语言 ...
- DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用
CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()), --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...
- Django之REST framework源码分析
前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...
- Django(60)Django内置User模型源码分析及自定义User
前言 Django为我们提供了内置的User模型,不需要我们再额外定义用户模型,建立用户体系了.它的完整的路径是在django.contrib.auth.models.User. User模型源码分析 ...
- Django(64)频率认证源码分析与自定义频率认证
前言 有时候我们发送手机验证码,会发现1分钟只能发送1次,这是做了频率限制,限制的时间次数,都由开发者自己决定 频率认证源码分析 def check_throttles(self, request): ...
- [Abp 源码分析]十一、权限验证
0.简介 Abp 本身集成了一套权限验证体系,通过 ASP.NET Core 的过滤器与 Castle 的拦截器进行拦截请求,并进行权限验证.在 Abp 框架内部,权限分为两块,一个是功能(Featu ...
- Python学习---Django的request.post源码分析
request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去
随机推荐
- JSONP跨域资源共享的安全问题
目录 关于 JSONP 一.JSON 劫持 二.Callback 可定义导致的安全问题 三.其他文件格式( Content-Type )与 JSON 四.防御 摘自:http://blog.known ...
- Run-Time Check Failure #0,The value of ESP was not properly saved 错误解决
调用DLL函数,出现错误 Run-Time Check Failure #0 - The value of ESP was not properly saved across a function c ...
- Elasticsearch exception [type=mapper_parsing_exception, reason=No type specified for field [X]
可能原因是实体类属性没有指定映射类型 创建mapping时需要指定field的type,如果不指定则报错 错误 //这是一个类中的字段 @Field(store = false) private St ...
- Compare the contents of two arrays
✍️Define a methed to compare the contents of two arrays and return the result . 定义一个方法,用于比较两个数组的内容是否 ...
- 【】maven 配置启动tomcat版本,修改默认的6.x.x版本
<build> <plugins> <!-- 配置Tomcat插件 ,用于启动项目 --> <plugin> <groupId>org.ap ...
- 多线程-2.线程创建方式和Thread类
线程的创建方式 1.继承Thread类,重写run方法,示例如下: 1 class PrimeThread extends Thread { 2 long minPrime; 3 PrimeThrea ...
- c++debug&注意事项 自用 持续更新
cin后回车程序直接退出: 加system("pause");在return 0;前面 C++ 控制cout输出的小数位数 C++中的cout.setf().cout.precis ...
- (转)elasticsearch连接不到head插件解决方案
(1)elasticsearch-5x下的 config/elasticsearch.yml http.cors.enabled: true http.cors.allow-origin: & ...
- Class和ClassLoader的getResource方法对比
最近在看写Spring的源代码,里面有好多地方都用到了Class和ClassLoader类的getResource方法来加载资源文件.之前对这两个类的这个方法一知半解,概念也很模糊,这边做下整理,加深 ...
- Java数组学习之前基础小案例
不多说,1天时间看完数组之前内容,这就靠代码的实践总结一下吧~~ 打印三角形 简单易懂,初学都会,就不注释了,前者为取巧的三角形实现方法,我注释了,直接上源码~~ public class Trian ...