三、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 ...
随机推荐
- JS开启浏览器全屏模式,需要手动触发
<html > <meta charset="UTF-8"> <body> <button onclick="launchFul ...
- java并发实践笔记
底层的并发功能与并发语义不存在一一对应的关系.同步和条件等底层机制在实现应用层协议与策略须始终保持一致.(需要设计级别策略.----底层机制与设计级策略不一致问题). 简介 1.并发简史.(资源利用率 ...
- python 9*9 乘法表
row = 1 while row <= 9: col = 1 while col <= row: print('%d*%d=%d'%(col, row, row*col), end='\ ...
- jquery bxslider幻灯片样式改造
找了很多jquery的幻灯片,都觉得不是很好,最后发现bxslider兼容性最好,移动设备支持手动翻动. 但是官方提供的显示效果真的很难看,让人难以接受.最后只能自己DIY了. bxslider官方样 ...
- php的几个实用正则表达式
更多内容推荐微信公众号,欢迎关注: 此文章是网上搜索而来: 对于开发人员来说,正则表达式是一个非常有用的功能,它提供了 查找,匹配,替换 句子,单词,或者其他格式的字符串.这篇文章主要介绍了15个超实 ...
- [转]GCC常用参数详解
简介gcc and g++现在是gnu中最主要和最流行的c & c++编译器 .gcc/g++在执行编译工作的时候,总共需要以下几步:1.预处理,生成.i的文件[预处理器cpp]2.将预处理后 ...
- AS中一些不经常用到的快捷键
1 书签 添加/移除书签 Ctrl+shift+F11 展示书签 shift+F11 下一个书签 shift+加号 上一个书签 shift+减号 2 折叠/展开代码块 展开代码块 ctrl+加号 ...
- 【codeforces】【比赛题解】#854 CF Round #433 (Div.2)
cf一如既往挺丧 看丧题点我! [A]分数 Petya是数学迷,特别是有关于分数的数学.最近他学了所谓一个分数被叫做“真分数”当且仅当其分子小于分母,而一个分数被叫做“最简分数”当且仅当其分子分母互质 ...
- marshmallow: 简化Python对象系列化
转载:http://www.thinksaas.cn/topics/0/594/594368.html marshmallow -一个轻量级的库用于将复杂对象转成简单的Python数据类型.或从简单的 ...
- docker stack 部署 seafile(http)
=============================================== 2018/5/13_第1次修改 ccb_warlock == ...