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源码之权限流程剖析的更多相关文章

  1. 二、django rest_framework源码之认证流程剖析

    1 绪言 上一篇中讲了django rest_framework总体流程,整个流程中最关键的一步就是执行dispatch方法.在dispatch方法中,在调用了一个initial方法,所有的认证.权限 ...

  2. 一、django rest_framework源码之总体流程剖析

    1 序言 有如下django代码,视图层: from django.http import HttpResponse from rest_framework.views import APIView ...

  3. 六、django rest_framework源码之解析器剖析

    1 绪论 网络传输数据只能传输字符串格式的,如果是列表.字典等数据类型,需要转换之后才能使用但是我们之前的rest_framework例子都没有转换就直接可以使用了,这是因为rest_framewor ...

  4. 四、django rest_framework源码之频率控制剖析

    1 绪言 权限判定之后的下一个环节是访问频率控制,本篇我们分析访问频率控制部分源码. 2 源码分析 访问频率控制在dispatch方法中的initial方法调用check_throttles方法开始. ...

  5. 七、django rest_framework源码之视图

    1 绪言 当大家看大这篇博文的时候,应该对Django rest_framework中的CBV有所了解了,大致来说就是通过定义类来继承APIView类,并在类中定义get.post.put.delet ...

  6. 五、django rest_framework源码之版本控制剖析

    1 绪论 Djangorest_framework的版本控制允许用户更改不同客户端之间的行为,且提供了许多不同的版本控制方案.版本控制由传入的客户端请求确定,可以基于请求URL,也可以基于请求标头. ...

  7. Django session 源码流程

    流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...

  8. 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)

    关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/11/es-code02/ 前提 上篇文章写了 ElasticSearch 源码解析 -- ...

  9. Django对中间件的调用思想、csrf中间件详细介绍、Django settings源码剖析、Django的Auth模块

    目录 使用Django对中间件的调用思想完成自己的功能 功能要求 importlib模块介绍 功能的实现 csrf中间件详细介绍 跨站请求伪造 Django csrf中间件 form表单 ajax c ...

随机推荐

  1. pandas 视频讲座 from youtube

    Stephen Simmons - Pandas from the inside - YouTube https://www.youtube.com/watch?v=Dr3Hv7aUkmU 2016年 ...

  2. 读懂复杂C声明的黄金法则

    在网上遇见felix,他让我读 http://www.felix021.com/blog/read.php?2072,读完之后觉得收获很大,需要练习一下. 黄金法则:从声明的变量开始,先向右看,再向左 ...

  3. bzoj 1044 [HAOI2008]木棍分割(二分+贪心,DP+优化)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1044 [题意] n根木棍拼到一起,最多可以切m刀,问切成后最大段的最小值及其方案数. ...

  4. 【leetcode 简单】 第五十六题 快乐数

    编写一个算法来判断一个数是不是“快乐数”. 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1.如 ...

  5. sql____001

    题目: create table my_001 (id int,value int); insert into my_001 values(1,10): insert into my_001 valu ...

  6. 【CTF WEB】GCTF-2017读文件

    读文件 只给了个1.txt可以读,试了一下加*不行,感觉不是命令执行,"../"返回上级目录也不行,猜测可能过滤了什么,在1.txt中间加上"./"发现仍能读取 ...

  7. CertUtil.exe被利用来下载恶意软件

    1.前言 经过国外文章信息,CertUtil.exe下载恶意软件的样本. 2.实现原理 Windows有一个名为CertUtil的内置程序,可用于在Windows中管理证书.使用此程序可以在Windo ...

  8. RabbitMQ--work queues(二)

    封装一个task到一个message,并发送到queue.consumer会去除task并执行这个task. 这里我们简化了操作,发送消息到队列中,consumer取出消息计算里面'.'号有几个就sl ...

  9. 数据库-mysql触发器

    MySQL包含对触发器的支持.触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行. 一:创建触发器 在MySQL中,创建触发器语法 ...

  10. 虚拟机 CentOS7 64

    下载地址:https://www.centos.org/download/ 下载完后以后使用虚拟机安装即可