Django-Rest-Framework 权限管理源码浅析(小结)


Posted in Python onNovember 12, 2018

在django的views中不论是用类方式还是用装饰器方式来使用rest框架,django_rest_frame实现权限管理都需要两个东西的配合: authentication_classespermission_classes

# 方式1: 装饰器
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response


@api_view(["GET", ])
@permission_classes([AllowAny,])
@authentication_classes([SessionAuthentication, BasicAuthentication])
def test_example(request):
 content = {
   'user': unicode(request.user), # `django.contrib.auth.User` instance.
   'auth': unicode(request.auth), # None
  }
  return Response(content)

# ------------------------------------------------------------
# 方式2: 类
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
 authentication_classes = (SessionAuthentication, BasicAuthentication)
 permission_classes = (AllowAny,)

 def get(self, request, format=None):
  content = {
   'user': unicode(request.user), # `django.contrib.auth.User` instance.
   'auth': unicode(request.auth), # None
  }
  return Response(content)

上面给出的是权限配置的默认方案,写和不写没有区别。 rest框架有自己的settings文件 ,最原始的默认值都可以在里面找到:

Django-Rest-Framework 权限管理源码浅析(小结)

说道rest的settings文件,要覆盖其中的默认行为,特别是权限认证行为,我们只需要在 项目settings文件

中指定你自己的类即可:

REST_FRAMEWORK = {
 ...
 'DEFAULT_AUTHENTICATION_CLASSES': (
  'your_authentication_class_path',
 ),
 ...
}

在rest的settings文件中,获取属性时,会优先加载项目的settings文件中的设置,如果项目中没有的,才加载自己的默认设置:

初始化api_settings对象

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)

APISettings 类中获取属性时优先获取项目的settings文件中 REST_FRAMEWORK 对象的值,没有的再找自己的默认值

@property
def user_settings(self):
 if not hasattr(self, '_user_settings'):
  # _user_settings默认为加载项目settings文件中的REST_FRAMEWORK对象
  self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
 return self._user_settings

def __getattr__(self, attr):
 if attr not in self.defaults:
  raise AttributeError("Invalid API setting: '%s'" % attr)

 try:
  # Check if present in user settings
  # 优先加载user_settings,即项目的settings文件,没有就用默认
  val = self.user_settings[attr]
 except KeyError:
  # Fall back to defaults
  val = self.defaults[attr]

 # Coerce import strings into classes
 if attr in self.import_strings:
  val = perform_import(val, attr)

 # Cache the result
 self._cached_attrs.add(attr)
 setattr(self, attr, val)
 return val

在rest中settings中,能自动检测 项目settings 的改变,并重新加载自己的配置文件:

Django-Rest-Framework 权限管理源码浅析(小结)

权限管理原理浅析

rest框架是如何使用 authentication_classespermission_classes ,并将二者配合起来进行权限管理的呢?

使用类方式实现的时候,我们都会直接或间接的使用到rest框架中的APIVIEW,在 urls.py 中使用该类的 as_view 方法来构建router

# views.py
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated


class ExampleAPIView(APIView):
 permission_classes = (IsAuthenticated,)
 ...
 
# -----------------------------
from django.conf.urls import url, include

from .views import ExampleAPIView

urlpatterns = [
 url(r'^example/(?P<example_id>[-\w]+)/examples/?$',
  ExampleAPIView.as_view()),
]

在我们调用 APIVIEW.as_view() 的时候,该类会调用父类的同名方法:

Django-Rest-Framework 权限管理源码浅析(小结)

父类的同名方法中,调用了dispatch方法:

Django-Rest-Framework 权限管理源码浅析(小结)

rest 重写 了该方法,在该方法中对requset做了一次服务端初始化(加入验证信息等)处理

Django-Rest-Framework 权限管理源码浅析(小结)

调用权限管理

Django-Rest-Framework 权限管理源码浅析(小结)

在权限管理中会使用默认的或是你指定的权限认证进行验证: 这里只是做验证并存储验证结果 ,这里操作完后authentication_classes的作用就完成了。验证结果会在后面指定的 permission_classes 中使用!

def get_authenticators(self):
  """
  Instantiates and returns the list of authenticators that this view can use.
  """
  return [auth() for auth in self.authentication_classes]

通过指定的permission_classes确定是否有当前接口的访问权限:

class IsAuthenticatedOrReadOnly(BasePermission):
 """
 The request is authenticated as a user, or is a read-only request.
 """

 def has_permission(self, request, view):
  return (
   request.method in SAFE_METHODS or
   request.user and
   request.user.is_authenticated
  )

最后,不管有没有使用permission_classes来决定是否能访问,默认的或是你自己指定的authentication_classes都会执行并将权限结果放在request中!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解python之多进程和进程池(Processing库)
Jun 09 Python
python的pdb调试命令的命令整理及实例
Jul 12 Python
python爬取淘宝商品详情页数据
Feb 23 Python
Python向MySQL批量插数据的实例讲解
Mar 31 Python
windows下python安装pip图文教程
May 25 Python
Python使用matplotlib绘制三维参数曲线操作示例
Sep 10 Python
pygame实现成语填空游戏
Oct 29 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
解决ROC曲线画出来只有一个点的问题
Feb 28 Python
Pyecharts 中Geo函数常用参数的用法说明
Feb 01 Python
python FTP编程基础入门
Feb 27 Python
Python torch.flatten()函数案例详解
Aug 30 Python
使用python将时间转换为指定的格式方法
Nov 12 #Python
pandas 快速处理 date_time 日期格式方法
Nov 12 #Python
python内置数据类型之列表操作
Nov 12 #Python
python pandas读取csv后,获取列标签的方法
Nov 12 #Python
对pandas的行列名更改与数据选择详解
Nov 12 #Python
Python numpy.array()生成相同元素数组的示例
Nov 12 #Python
浅谈numpy生成数组的零值问题
Nov 12 #Python
You might like
使用php判断浏览器的类型和语言的函数代码
2013/02/28 PHP
php中AES加密解密的例子小结
2014/02/18 PHP
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
PHP使用PDO实现mysql防注入功能详解
2019/12/20 PHP
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
公共js在页面底部加载的注意事项介绍
2013/07/18 Javascript
方便实用的jQuery checkbox复选框全选功能简单实例
2013/10/09 Javascript
html文件中jquery与velocity变量中的$冲突的解决方法
2013/11/01 Javascript
Javascript 运动中Offset的bug解决方案
2014/12/24 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
Vue props用法详解(小结)
2018/07/03 Javascript
JavaScript位置参数实现原理及过程解析
2020/09/14 Javascript
[01:58]2018DOTA2亚洲邀请赛趣味视频——交流
2018/04/03 DOTA
Python实现抓取网页并且解析的实例
2014/09/20 Python
在Python程序中进行文件读取和写入操作的教程
2015/04/28 Python
对python pandas 画移动平均线的方法详解
2018/11/28 Python
浅谈python 导入模块和解决文件句柄找不到问题
2018/12/15 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
Python入门Anaconda和Pycharm的安装和配置详解
2019/07/16 Python
python中pathlib模块的基本用法与总结
2020/08/17 Python
python实现代码审查自动回复消息
2021/02/01 Python
Steve Madden官网:美国鞋类品牌
2017/01/29 全球购物
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
红色连衣裙精品店:Red Dress Boutique
2018/08/11 全球购物
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
会计专业应届生自荐信
2014/02/07 职场文书
2014年扶贫帮困工作总结
2014/12/09 职场文书
务工证明怎么写
2015/06/18 职场文书
mysql数据库隔离级别详解
2022/06/16 MySQL
一文解答什么是MySQL的回表
2022/08/05 MySQL
JS前端使用Canvas快速实现手势解锁特效
2022/09/23 Javascript