Django Rest Framework之权限
基本代码结构
url.py:
- from django.conf.urls import url, include
- from app import views
- urlpatterns = [
- url(r'^test/', views.TestView.as_view()),
- ]
views.py:
- from rest_framework.views import APIView
- from rest_framework.response import Response
- from rest_framework.request import Request
- from rest_framework import exceptions
- class MyPermission(object):
- def has_permission(request, self):
- '''
- 权限代码编写区域
- '''
- return True #权限通过 如果权限不通过 返回False
- class TestView(APIView):
- permission_classes = [MyPermission, ]
- def get(self, request, *args, **kwargs):
- pass
- def post(self, request, *args, **kwargs):
- pass
- '''
- 等等一系列的视图功能方法
- '''
说明:
- has_permission方法的返回值是布尔类型,True表示权限通过,False表示权限拒绝
- 上面的基本结构是做局部的类的权限判断方式,全局权限判断后文介绍。
- permission_classes属性变量同样也是一个列表,列表元素是权限判断类。
源码分析
其实权限的源码流程跟认证的流程基本相同。还是要抓住通过源码要想知道什么,不然就会陷入浩如烟海的源码之中。
为什么会使用permission_classes属性变量?
python 的面向对象编程中,我们首先要执行的方法肯定是dispatch方法,所以我们的分析入口就是dispatch方法,在dispatch方法中,可以看到,通过initialize_request方法将django原生的request进行了一次封装。由initialize_request方法的实现过程可以看出,将其封装实例化成了一个Request对象。但权限判断并没有像认证一样初始化到了Request对象中,但对django原生的request封装还是需要强调的,因为编写代码的过程中对django原生的request的使用是必不可免的。
同样的,权限判断的具体过程跟认证一样,也是在dispatch方法中所调用的initial方法中实现。再跳转到initial方法中去。
在initial方法中,可以看到权限判断的方法,没错,就是通过check_permissions方法实现的。再跳转到这个方法中去。
在check_permissions方法中,就可以看到权限的判断就是通过这个for循环实现的。正因为在业务代码中可能存在若干种类型的权限判断,所以才会通过循环去执行我们定义好的权限判断类来完成多个权限体系的判断功能。这样,我们可以感觉到这里的“self.get_permissions()”的返回值应该就是我们在视图类中赋值过的permissions_classes属性变量的值。那就跳转到这个方法中去看看吧。
在get_permissions方法中看到,跟认证一样,返回值同样是一个列表生成式,而这个列表生成式使用的属性变量正是我们赋值过的permission_classes,跟我们之前的猜测完全一致。综上所述,我们为了让drf接口源码使用上我们自己定义的权限判断类,那我们就必须按照源码中写的借口,将permission_classes属性变量赋值
在权限判断类中为什么会定义一个名称为has_permission的方法?
回到check_permissions方法中,我们看if判断句,前面刚刚说过,在for中的permission其实就是我们自己定义的权限判断类,那么在if句中的“.has_permission(request,self)”不就应该就是Mypermission类中的方法吗?所以,我们自己定义的Mypermission类中一定要实现has_permission这个方法。(要注意这个方法的参数)
has_permission方法中,为什么返回值为布尔值?
还是跟上一个问题一样的,在上图中的if句中,我们可以看到“permission.has_permission(request, self)”的返回值不就是布尔值吗,这个返回值不就是has_permission方法返回值吗?当返回值为False时,就会执行if句中的代码,来抛出异常。
实例
- from django.conf.urls import url, include
- from web.views import TestView
- urlpatterns = [
- url(r'^test/', TestView.as_view()),
- ]
urls.py
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- from rest_framework.views import APIView
- from rest_framework.response import Response
- from rest_framework.authentication import BaseAuthentication
- from rest_framework.permissions import BasePermission
- from rest_framework.request import Request
- from rest_framework import exceptions
- token_list = [
- 'sfsfss123kuf3j123',
- 'asijnfowerkkf9812',
- ]
- class TestAuthentication(BaseAuthentication):
- def authenticate(self, request):
- """
- 用户认证,如果验证成功后返回元组: (用户,用户Token)
- :param request:
- :return:
- None,表示跳过该验证;
- 如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
- self._authenticator = None
- if api_settings.UNAUTHENTICATED_USER:
- self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户
- else:
- self.user = None
- if api_settings.UNAUTHENTICATED_TOKEN:
- self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None
- else:
- self.auth = None
- (user,token)表示验证通过并设置用户名和Token;
- AuthenticationFailed异常
- """
- val = request.query_params.get('token')
- if val not in token_list:
- raise exceptions.AuthenticationFailed("用户认证失败")
- return ('登录用户', '用户token')
- def authenticate_header(self, request):
- """
- Return a string to be used as the value of the `WWW-Authenticate`
- header in a `401 Unauthenticated` response, or `None` if the
- authentication scheme should return `403 Permission Denied` responses.
- """
- pass
- class TestPermission(BasePermission):
- message = "权限验证失败"
- def has_permission(self, request, view):
- """
- 判断是否有权限访问当前请求
- Return `True` if permission is granted, `False` otherwise.
- :param request:
- :param view:
- :return: True有权限;False无权限
- """
- if request.user == "管理员":
- return True
- # GenericAPIView中get_object时调用
- def has_object_permission(self, request, view, obj):
- """
- 视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证
- Return `True` if permission is granted, `False` otherwise.
- :param request:
- :param view:
- :param obj:
- :return: True有权限;False无权限
- """
- if request.user == "管理员":
- return True
- class TestView(APIView):
- # 认证的动作是由request.user触发
- authentication_classes = [TestAuthentication, ]
- # 权限
- # 循环执行所有的权限
- permission_classes = [TestPermission, ]
- def get(self, request, *args, **kwargs):
- # self.dispatch
- print(request.user)
- print(request.auth)
- return Response('GET请求,响应内容')
- def post(self, request, *args, **kwargs):
- return Response('POST请求,响应内容')
- def put(self, request, *args, **kwargs):
- return Response('PUT请求,响应内容')
views.py
扩展:全局权限
同样,跟全局认证一样,我们只需要在settings配置文件中添加配置项即可。然后,我们仍然需要将我们自定义的权限类也写到我们在跟views.py同级目录下新建的文件夹(我习惯叫utils)中的权限判断文件(permision.py)中去。
- REST_FRAMEWORK = {
- "DEFAULT_PERMISSION_CLASSES" :['api.utils.permission.Mypermission',]
- }
Mypermission就是我们写在utils文件夹中permission.py文件中的一个权限类。
注意:如果有部分类不需要权限判断的话,可以在Mypermission类中添加“permission_classes = []”,即可。
Django Rest Framework之权限的更多相关文章
- Django Rest framework 之 权限
django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) django res ...
- Django REST framework认证权限和限制和频率
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
- Django REST Framework 认证 - 权限 - 限制
一. 认证 (你是谁?) REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 自定义Token认证 第一步 : 建表>>>> 定义一个 ...
- Django REST Framework之权限组件
权限控制是如何实现的? 一般来说,先有认证才有权限,也就是用户登录后才能判断其权限,未登录用户给他一个默认权限. Django接收到一个请求,首先经过权限的检查,如果通过检查,拥有访问的权限,则予以放 ...
- Django REST framework认证权限和限制 源码分析
1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...
- Django Rest Framework源码剖析(二)-----权限
一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...
- Django Rest framework 之 序列化
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- Django Rest framework 之 解析器
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- Django Rest framework 之 版本
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
随机推荐
- InternalResourceViewResolver视图解析器(转)
转载地址:https://www.cnblogs.com/liruiloveparents/p/5054605.html springmvc在处理器方法中通常返回的是逻辑视图,如何定位到真正的页面,就 ...
- Vuejs——(12)组件——动态组件
版权声明:出处http://blog.csdn.net/qq20004604 目录(?)[+] 本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...
- House of Spirit学习调试验证与实践
作家:Bug制造机 原文来自:House of Spirit学习调试验证与实践 House of Spirit和其他的堆的利用手段有所不同.它是将存在的指针改写指向我们伪造的块(这个块可以位于堆.栈. ...
- bootstrap使用之多个弹窗和拖动效果[开发篇]
有时开发一些特效,自己感觉挺爽的,像操作自己电脑一样操作你的网页,这里就介绍一个使用bootstrap的一点多窗口和拖动效果吧! 这里,我们不使用静态打开的的方式,low...,1.添加一个a链接 触 ...
- ASP.NET Core中自定义路由约束
路由约束 ASP.NET Core中,通过定义路由模板,可以在Url上传递变量,同时可以针对变量提供默认值.可选和约束. 约束的使用方法是在属性路由上添加指定的约束名,用法如下: // 单个使用 [R ...
- mysql之CREATE DATABASE Syntax(创建数据库)
一:语法 CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name #SCHEMA是DATABASE的同义词 [IF NOT EXITTS]可防止建库是已经 ...
- Xamarin.Android 本地数据库 SQLiteDatabase 操作
目的:使用 SQLiteDatabase 创建本地数据库.表,并对数据进行增删改查操作. 引用命名空间: using Android.App; using Android.Widget; using ...
- 用eclipse导入打war包的maven项目
最近遇到Maven管理下的Spring MVC项目,组内某位将项目代码扔过来,一脸懵逼(囧),查阅了一些资料后终于将此项目运行通了(>_<),特此记录下来与各位分享. 通俗的来说,Mave ...
- pycharm 安装第三方库报错:AttributeError: 'module' object has no attribute 'main'
pip升级到 10.0.1 之后 老版的pycharm 使用pip安装第三方库的时候会报错,报错如上图所示: 其主要原因是 新版的 pip 更改了 部分api 将其中 pip.main() 改为 pi ...
- Spring Boot SSL [https]配置例子
前言 本文主要介绍Spring Boot HTTPS相关配置,基于自签证书实现: 通过本例子,同样可以了解创建SSL数字证书的过程: 本文概述 Spring boot HTTPS 配置 server. ...