Django Rest framework 之 权限
- django rest framework 之 认证(一)
- django rest framework 之 权限(二)
- django rest framework 之 节流(三)
- django rest framework 之 版本(四)
- django rest framework 之 解析器(五)
- django rest framework 之 序列化(六)
- django rest framework 之 分页(七)
- django rest framework 之 视图(八)
一、权限实例
在阅读本文之前请先参考django rest framework 之 认证中关于django rest framework的相关内容及实例
1、目录结构
为了更好的管理各个功能组件,在django rest framework 之 认证中我们说到可以将认证类单独的拿出来,放到其他目录下,然后导入到views.py 文件中,在权限环节我们亦可以这么做,目录结构就变成这样

在api这个app下创建一个utils包专门用来存放相关的组件。
2、为模型类添加认证字段
我们在models.py中定义了两个模型类,分别是
from django.db import models
class UserInfo(models.Model):
USER_TYPE = (
(1,'普通用户'),
(2,'VIP'),
(3,'SVIP')
)
user_type = models.IntegerField(choices=USER_TYPE, default=1)
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
class UserToken(models.Model):
user = models.OneToOneField(UserInfo,on_delete=models.CASCADE)
token = models.CharField(max_length=64)
在UserInfo中通过为用户添加一个user_type字段来保证用户的身份,是普通用户,VIP还是SVIP,这样就可以通过用户的身份验证不同的权限。如果想要定义一个视图类,这个类中的逻辑只有超级用户才能访问。
3、具体权限认证
可以再utils中的permissions.py中这么写
# utils/permission.py
class SVIPPremission(object):
message = "必须是SVIP才能访问" # 这里的message表示如果不通过权限的时候,错误提示信息
def has_permission(self,request,view):
if request.user.user_type != 3:
return False
return True
class MyPremission(object):
# 这个权限类表示当用户为SVIP时不可通过
def has_permission(self,request,view):
if request.user.user_type == 3:
return False
return True
这里只是判断用户的USER_TYPE的字段,判断用户是否有权限,也可以添加其他的逻辑进行判断。
4、全局配置
在上一节的django rest framework 之 认证的认证中,将认证类放到了settings.py文件中,这样会作用到视图中的每一个视图类,如果视图类想要自己进行认证,只需要重写authentication_classes即可,那么对于权限来说我们也可以这么做,
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.authenticate.FirstAuthenticate', 'api.utils.authenticate.MyAuthenticate'],
"UNAUTHENTICATED_USER": None, # 匿名,request.user = None
"UNAUTHENTICATED_TOKEN": None,# 匿名,request.auth = None
"DEFAULT_PERMISSION_CLASSES": ['api.utils.permission.MyPermission'], # 表示每一个视图类(只要不重写permission_classes属性),都需要SVIP的用户才能访问。
}
5、视图
在视图view.py中定义一个用户详情类UserInfoView作为测试,这里的视图和上一节的django rest framework 之 认证是相接的。
from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.views import View
from rest_framework.views import APIView
from rest_framework.request import Request
from .utils import authenticate, permission
from api import models
import json
def md5(user):
import hashlib
import time
# 当前时间,相当于生成一个随机的字符串
ctime = str(time.time())
# token加密
m = hashlib.md5(bytes(user, encoding='utf-8'))
m.update(bytes(ctime, encoding='utf-8'))
return m.hexdigest()
class AuthView(APIView):
'''用于用户登录验证'''
authentication_classes = [] #里面为空,代表不需要认证
permission_classes = [] #不里面为空,代表不需要权限
def get(self, request, *args, **kwargs):
ret = {'code': 1000, 'msg': 'success', 'name': '偷偷'}
ret = json.dumps(ret, ensure_ascii=False)
return HttpResponse(ret)
def post(self,request,*args,**kwargs):
ret = {'code':1000,'msg':None}
try:
user = request.POST.get('username')
pwd = request.POST.get('password')
print(user, pwd)
obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
print(obj.username, obj.password)
if not obj:
ret['code'] = 1001
ret['msg'] = '用户名或密码错误'
#为用户创建token
token = md5(user)
#存在就更新,不存在就创建
models.UserToken.objects.update_or_create(user=obj,defaults={'token':token})
ret['token'] = token
except Exception as e:
ret['code'] = 1002
ret['msg'] = '请求异常'
return JsonResponse(ret)
ORDER_DICT = {
1:{
'name':'apple',
'price':15
},
2:{
'name':'狗子',
'price':100
}
}
class OrderView(APIView):
# 用户想要获取订单,就要先通过身份认证、在全局settings.py 中已经配置
permission_classes = []
def get(self, request, *args, **kwargs):
ret = {
'code': 1024,
'msg': '订单获取成功',
}
try:
ret['data'] = ORDER_DICT
except Exception as e:
pass
return JsonResponse(ret)
class UserInfoView(APIView):
permission_classes = [permission.SVIPPermission]
def get(self, request, *args, **kwargs):
print(request.user)
return HttpResponse('SVIP用户信息')
这里的UserInfoView重写了permission_classes属性,则不会再使用settings.py中关于认证类的配置。表示只有SVIP才能访问这个类的内部。
6、路由分发
在url.py中设置路由分发
from django.conf.urls import url
from api.views import AuthView, OrderView, UserInfoView
urlpatterns = [
url(r'^api/v1/auth/$', AuthView.as_view()),
url(r'^api/v1/order/$', OrderView.as_view()),
url(r'^api/v1/info/$', UserInfoView.as_view()),
]
7、请求测试
Postman或者浏览器发送请求,由于我们在setting.py中配置了 'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.authenticate.FirstAuthenticate', 'api.utils.authenticate.MyAuthenticate'],
会对请求进行认证,所以要带这用户的token才能通过,进入到权限组件。
进入sqlite数据库,找到对应的注册用户

在数据库中,拿到刷新的用户的最近一次的token

拿到这个token发送请求

请求成功,则说明权限生效,也可以在将UserInfoView改成如下
class UserInfoView(APIView):
permission_classes = [permission.SVIPPermission]
def get(self, request, *args, **kwargs):
print(request.user)
return HttpResponse('SVIP用户信息')
在发送请求,就会发现用户不会有权限的提示信息。如下

二、源码分析
像django rest framework 之 认证一样进入,request的请求流程,进入源码查看具体权限的操作
1、进入dispath()方法

2、进入initial()方法

3、进入check_permissions()方法

4、权限类的具体操作
在这里可以看到和认证中有类似的操作,获取所有的权限类,并且执行每一个权限类的has_permission()方法,而这个方法具体封装了我们的判断权限操作,但是has_permission()方法的返回值需要时False或者True, self.permission_denied(request, message=getattr(permission, 'message', None))说明可以在权限类中重写message属性,来定义权限不通过时候的提示信息。

进入self.get_permissions()来看一下
4、获取所有的权限类


在APIView中有定义默认的权限类,因此也可以通过全局配置的方法配置权限类。
5、原生的权限类
像认证那样,django rest framework中也有权限类

可以根据自己的需要调用。
三、总结
权限其实的流程跟之前的认证流程是一样的,认证类封装到request中,然后再调用认证类的方法,不过这里的方法返回值不再是像认证组件那样的直接返回一个认证的对象,而是返回一个True或者False值表示认证过的对象是否有某些权限再进行具体操作。
这里注意的是,在自己重写权限类的相关方法,添加自己的逻辑的时候,返回值需要是一个布尔值,Flase或者True,表示是否有权限。也可以通过全局配置和局部配置权限类。
Django Rest framework 之 权限的更多相关文章
- Django REST framework认证权限和限制和频率
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
- Django Rest Framework之权限
基本代码结构 url.py: from django.conf.urls import url, include from app import views urlpatterns = [ url(r ...
- 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 之 节流(三) ...
随机推荐
- EBS CAS SSO测试
https://wiki.jasig.org/display/CAS/CASifying+Oracle+Portal https://wenku.baidu.com/view/5f110a85b9d5 ...
- CNN 文本分类
谈到文本分类,就不得不谈谈CNN(Convolutional Neural Networks).这个经典的结构在文本分类中取得了不俗的结果,而运用在这里的卷积可以分为1d .2d甚至是3d的. 下面 ...
- 13.翻译系列:Code-First方式配置多对多关系【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code- ...
- 为什么 echo 3 . print(2) . print(4) . 5 . 'c'的结果是45c2131
例子:请写出echo 3 . print(2) . print(4) . 5 . 'c'的输出结果为____? 许多人看到这个题的第一印象是输出结果不就是3245c嘛,然而正确的是答案却是45c213 ...
- Linux下解压.tar.xz格式文件的方法
前言 对于xz这个压缩相信很多人陌生,但xz是绝大数linux默认就带的一个压缩工具,xz格式比7z还要小. 今天在下载Node.js源码包的时候遇到的这种压缩格式.查了一下资料,这里进行一下记录,分 ...
- 构建NTP时间服务器
NTP服务器是用于局域网服务器时间同步使用的,可以保证局域网所有的服务器与时间服务器的时间保持一致,某些应用对时间实时性要求高的必须统一时间. 互联网的时间服务器也有很多,例如ntpdate ntp. ...
- linux中一些简便的命令之wc
wc命令是统计文本中的字符数.单词数以及文本行数的,具体参数如下: -l 统计文本中的行数 -w 统计文本中的单词数 -c/m 统计文本中的字符数 -L 统计文本中最长行的字符数 当然使用时也可以不带 ...
- 解决Chrome浏览器主页被hao123、360和2345篡改简单有效方法
转自:https://blog.csdn.net/qq_32635971/article/details/72793115?locationNum=10&fps=1 当你打开浏览器看到各种首页 ...
- Spring Cloud 微服务分布式链路跟踪 Sleuth 与 Zipkin
Zipkin 是一个开放源代码分布式的跟踪系统,由 Twitter 公司开源,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集.存储.查找和展现.它的理论模型来自于Google ...
- volatile 关键字了解与使用
前言 不管是在面试还是实际开发中 volatile 都是一个应该掌握的技能. 首先来看看为什么会出现这个关键字. 内存可见性 由于 Java 内存模型(JMM)规定,所有的变量都存放在主内存中,而每个 ...