三、django rest_framework源码之权限流程剖析
1 绪言
上一篇中分析了认证部分的源码,认证后的下一个环节就是权限判定了。事实上,权限判定肯定要与认证联合使用才行,因为认证部分不会对请求进行禁止或者是允许,而只是根据请求中用户信息进行用户身份判断,而权限判定就是认证中添加的用户身份进行权限判定。权限判定的入口在dispatch方法中调用的initial方法中,如下所示:
def initial(self, request, *args, **kwargs):
……
# Ensure that the incoming request is permitted
self.perform_authentication(request) #认证
self.check_permissions(request) #权限判定
self.check_throttles(request)
2 源码分析
当执行check_permissions方法的时候,权限判定也就开始了,贴出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) ) #有权限的话继续下一个权限类实例,直到遍历完所有实例
check_permissions方法首先遍历权限类实例列表,这个列表从哪来呢?我们看看get_permissions方法就知道了:
def get_permissions(self):
return [permission() for permission in self.permission_classes]
这两行代码有没有很眼熟?没错,在上一篇认证源码分析中也有一个列表生成式生成所有配置好的权限类实例,连读取权限类的方式都是一样的,与权限类不同的是,认证类的这个环境放在加工处理request请求的方法中,然后将所有认证类实例封装进了request中。当然,这跟权限类没关系,我们现在只需要知道这个方法会读取配置的权限类,然后依次实例化并返回列表。但值得注意的是,里面有一个message属性,是指拒绝访问之后返回的提示信息,自定义权限类的时候可以指定message的值。
在for循环中,不断遍历权限实例对象,执行它的has_permission方法,我们以djangorestfromework自带的AllowAny为例进行分析
class AllowAny(BasePermission): def has_permission(self, request, view): return True
AllowAny类的has_permission方法直接就返回一个True,因为AllowAny这个类的功能就是允许所有访问,也就是说在has_permission类中,如果允许访问,就返回True,拒绝访问就返回False。
权限实例对象列表中可能有多个权限类实例,只要有一个返回的是False,抛出异常,那么就拒绝访问。这个异常是就是在permission_denied方法中抛出的,这个方法会在has_permission方法返回False时执行,permission_denied的作用就是判断抛出那种异常,源码如下:
def permission_denied(self, request, message=None): if request.authenticators and not request.successful_authenticator: raise exceptions.NotAuthenticated() raise exceptions.PermissionDenied(detail=message)
如有所有权限类都遍历完了,都返回True,那么权限判定这个环节就结束了。
3 自定义权限类
自定义的权限类必须实现has_permission方法,另外可以在类中指定拒绝访问时的message,当然这不是必须的。以下是自定义的一个权限类,功能是只允许用户名为“admin”的用户访问,
拒绝其他所有用户,拒绝是提示“您不是admin用户,无权访问”:
from rest_framework.permissions import BasePermission class MyAdminPermission(BasePermission): message = '您不是admin用户,无权访问' def has_permission(self, request, view): if request.user == "admin": return True
4 配置权限类
配置权限类的方法和配置认证类差不多:
局部配置:
在视图类中加入以下代码:
DEFAULT_PERMISSION_CLASSES = [MyAdminPermission,]
注意:别忘了逗号。
全局配置:
在项目的settings.py文件中加入:
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'myapp.util.permission. MyAdminPermission ', ]
}
三、django rest_framework源码之权限流程剖析的更多相关文章
- 二、django rest_framework源码之认证流程剖析
1 绪言 上一篇中讲了django rest_framework总体流程,整个流程中最关键的一步就是执行dispatch方法.在dispatch方法中,在调用了一个initial方法,所有的认证.权限 ...
- 一、django rest_framework源码之总体流程剖析
1 序言 有如下django代码,视图层: from django.http import HttpResponse from rest_framework.views import APIView ...
- 六、django rest_framework源码之解析器剖析
1 绪论 网络传输数据只能传输字符串格式的,如果是列表.字典等数据类型,需要转换之后才能使用但是我们之前的rest_framework例子都没有转换就直接可以使用了,这是因为rest_framewor ...
- 四、django rest_framework源码之频率控制剖析
1 绪言 权限判定之后的下一个环节是访问频率控制,本篇我们分析访问频率控制部分源码. 2 源码分析 访问频率控制在dispatch方法中的initial方法调用check_throttles方法开始. ...
- 七、django rest_framework源码之视图
1 绪言 当大家看大这篇博文的时候,应该对Django rest_framework中的CBV有所了解了,大致来说就是通过定义类来继承APIView类,并在类中定义get.post.put.delet ...
- 五、django rest_framework源码之版本控制剖析
1 绪论 Djangorest_framework的版本控制允许用户更改不同客户端之间的行为,且提供了许多不同的版本控制方案.版本控制由传入的客户端请求确定,可以基于请求URL,也可以基于请求标头. ...
- Django session 源码流程
流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/11/es-code02/ 前提 上篇文章写了 ElasticSearch 源码解析 -- ...
- Django对中间件的调用思想、csrf中间件详细介绍、Django settings源码剖析、Django的Auth模块
目录 使用Django对中间件的调用思想完成自己的功能 功能要求 importlib模块介绍 功能的实现 csrf中间件详细介绍 跨站请求伪造 Django csrf中间件 form表单 ajax c ...
随机推荐
- Vim,Emacs排名不分先后
关键词:Vim,Emacs,Vim和Emacs之争 一同时提到vim和emacs,就几乎一定引发关于哪个更好的圣战.据说这个圣战从很早就开始了,偶尔还会有windows下的ultraedit的用户来凑 ...
- 20155214 2016-2017-2 《Java程序设计》第7周学习总结
20155214 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 UTC时间以Unix元年(1970年)为起点经过的秒数. ISO 8601并非年历系统,大部 ...
- 数据库(八)之T-SQL编程
什么是Transact-SQL? 结构化查询语言(SQL)是有美国国家标准协会(ANSI)和国际标准化组织(ISO)定义的标准,而Transact-SQL是Microsoft公司对此标准的一个实现. ...
- 微服务深入浅出(11)-- SpringBoot整合Docker
添加Dockerfile 在目录src/main/resources目录下店家Dockerfile文件: From java MAINTAINER "Eric"<eric.l ...
- 兴人类TDD培训札记
兴人类TDD培训札记 恰同学少年,风华正茂:书生意气,挥斥方遒 -- <沁园春 长沙> 幸之 前不久,非常幸运地全程参与了公司与南京5所知名高校合作的"兴人类TDD培训" ...
- windows环境cmd下执行jar
项目目录结构 一,在pom.xml文件里添加配置 <build> <plugins> <plugin> <groupId>org.apache.mave ...
- Linux输入子系统:多点触控协议 -- multi-touch-protocol.txt【转】
转自:http://blog.csdn.net/droidphone/article/details/8434768 Multi-touch (MT) Protocol --------------- ...
- u-boot移植随笔(7):u-boot启动流程简图【转】
转自:http://www.latelee.org/porting-uboot/u-boot-porting-bootstrap.html u-boot移植随笔:u-boot启动流程简图 画上面这张图 ...
- 2018Java开发面经(持续更新)
不要给自己挖坑!!!不要给自己挖坑!!!不要给自己挖坑!!!如果面试官只是问你了解xxx吗,如果不是很了解,就直接说不知道,不要说知道,不然面试官深问再不知道就印象很不好! 处女面送给了头条(北京)日 ...
- SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」
题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...