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. JQuery的选择器对控件ID含有特殊字符的解决方法-涨姿势了!

    1.jquery类库在我们实际项目中用的很多,大家经常需要根据控件的id,获取对应的html元素. 但是:当id含有特殊字符的时候,是不能选中的. 2. 自己简单的测试了下,jquery的id选择器只 ...

  2. ubuntu 开机自动挂在windows下的分区

    最近装了Ubuntu14.04 + windows7 的双系统,启动Ubuntu的时候,不会自动挂载win7的分区,只有我点击相应的硬盘符号时才会挂载/media下面.本着折腾到底的原则,在网上搜了搜 ...

  3. 【leetcode 简单】 第八十二题 反转字符串

    编写一个函数,其作用是将输入的字符串反转过来. 示例 1: 输入: "hello" 输出: "olleh" 示例 2: 输入: "A man, a p ...

  4. Linux基础-yum软件包管理

    任务目标:自定义yum仓库:createrepo,自定义repo文件,使用yum命令安装httpd软件包,卸载httpd软件包:yum –y remove 软件名 ,使用yum安装组件'KDE 桌面' ...

  5. bootstrap-table 应用

    更多内容推荐微信公众号,欢迎关注: 前端代码:js初始化表格,使用服务器端分页:<!DOCTYPE html> <html> <head> <meta cha ...

  6. mybatis模糊查询防止SQL注入

    SQL注入,大家都不陌生,是一种常见的攻击方式.攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=’1’”这样的语句),有可能入侵参数检验不足的应用程序.所以,在我们的应用 ...

  7. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  8. linux下定时器介绍1

    POSIX Timer 间隔定时器 setitimer 有一些重要的缺点,POSIX Timer 对 setitimer 进行了增强,克服了 setitimer 的诸多问题: 首先,一个进程同一时刻只 ...

  9. SVC 工作过程中出现的错误记录(SEO项目)

    1.同一のキーを含む項目が既に追加されています.追加的项目中含有重复主键) /seo' アプリケーションでサーバー エラーが発生しました. 同一のキーを含む項目が既に追加されています. 説明: 現在の ...

  10. orcale数据库分配用户

    account lock:创建用户的时候锁定用户 account unlock:创建用户的时候解锁用户,默认该选项 create user zhou8–用户名 identified by zhou88 ...