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的Twisted框架编写非阻塞程序的代码示例
May 25 Python
Python图形绘制操作之正弦曲线实现方法分析
Dec 25 Python
Python动刷新抢12306火车票的代码(附源码)
Jan 24 Python
python3库numpy数组属性的查看方法
Apr 17 Python
解决python3中cv2读取中文路径的问题
Dec 05 Python
Python简易版图书管理系统
Aug 12 Python
Python pandas库中的isnull()详解
Dec 26 Python
Python中用pyinstaller打包时的图标问题及解决方法
Feb 17 Python
Keras官方中文文档:性能评估Metrices详解
Jun 15 Python
Tensorflow tensor 数学运算和逻辑运算方式
Jun 30 Python
python 装饰器的基本使用
Jan 13 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
Feb 02 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的switch判断语句的“高级”用法详解
2014/10/01 PHP
php中curl使用指南
2015/02/05 PHP
PHP生成压缩文件实例
2015/02/07 PHP
js三种排序算法分享
2012/08/16 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
JavaScript中的原型继承基础学习教程
2016/05/06 Javascript
VUEJS实战之修复错误并且美化时间(2)
2016/06/13 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
jQuery中Nicescroll滚动条插件的用法
2016/11/10 Javascript
jQuery简单自定义图片轮播插件及用法示例
2016/11/21 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
2019/02/27 jQuery
跟老齐学Python之做一个小游戏
2014/09/28 Python
Python爬虫通过替换http request header来欺骗浏览器实现登录功能
2018/01/07 Python
深入理解Python爬虫代理池服务
2018/02/28 Python
Python后台管理员管理前台会员信息的讲解
2019/01/28 Python
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
Python实现基于SVM的分类器的方法
2019/07/19 Python
详解Python 中sys.stdin.readline()的用法
2019/09/12 Python
Python操作qml对象过程详解
2019/09/26 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
利用css3实现的简单的鼠标悬停按钮
2014/11/04 HTML / CSS
美国在线印刷公司:PsPrint
2017/10/12 全球购物
英国领先的运动营养品牌:Protein Dynamix
2018/01/02 全球购物
Gina Bacconi官网:吉娜贝康尼连衣裙和礼服
2018/04/24 全球购物
康拓普公司Java笔面试
2016/09/23 面试题
机电一体化专业推荐信
2013/12/03 职场文书
经贸日语专业个人求职信
2013/12/13 职场文书
经理管理专业毕业自荐书范文
2014/02/12 职场文书
精彩广告词大全
2014/03/19 职场文书
信访稳定工作汇报
2014/10/27 职场文书
2014年绩效考核工作总结
2014/12/11 职场文书
教师个人年度总结
2015/02/11 职场文书
同学聚会通知短信
2015/04/20 职场文书
2016春节放假通知范文
2015/08/18 职场文书
画错魏国疆域啦!《派对咖孔明》动画因作画失误于官网致歉
2022/04/07 日漫