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 之 节流(三) ...
随机推荐
- VS2017离线安装与Oracle数据库开发环境搭建
记得之前使用VS2015打开老的MVC4项目,不能右键创建控制器和添加视图,让我非常不习惯!找遍了网络无果,最后只能回到VS2013,但我就是不喜欢用旧的VS,这是不是病... 1.将VS2017离线 ...
- jzoj3156. 【GDOI2013模拟1】病毒传播
题意: 村庄里有m个人,初始有一些人感染了病毒.如果第i个人的编号i满足,有一对(a,b)(a是初始病毒感染者编号,b为前一天的感染者编号)使\(a*b mod m =i\),则第i个人会感染病毒.每 ...
- Flask实例化的参数 及 对app的配置
首先展示一下: from flask import Flask app = Flask(__name__) # type:Flask app.config["DEBUG"] = T ...
- H5内联视频
概述 微信上很多H5页面都会有会动的像视屏的页面,这样的效果很棒.从技术上来说,这个其实就是视屏,不过没有控制播放的按钮罢了.它们还有一个专业的名字--内联视频.下面我把自己对内联视屏的学习记录下来, ...
- 影响 POST 请求文件上传失败的几个环节的配置(php + nginx)
写在前面 最近写一个 php 接口,接受上传的文件,发现文件只要超过 5m 以上就会无响应失败,最后发现是 shadowsocks 的 timeout 设置问题(我全程开了全局的 VPN),但一开始并 ...
- 人脸检测第一文---A Dream of Spring
人脸识别研究的人很多,可是,真正具有划时代意义的还要当属Paul Viola的一篇文章<RobustReal-time Object Detection>.这篇文章让 人脸识别在实际应用中 ...
- 基于httpclient的效率优化
1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...
- [每天解决一问题系列 - 0011] 如何清除Windows中的Icon缓存
问题描述: 当更换一个应用或者快捷方式的图标后,会看到图标并没有及时更新 问题原因: 原因是Windows为了使图标显示更快,做了缓存%localappdata%\IconCache.db 解决方案: ...
- CentOS 6.5的安装详解(图文详解)
不多说,直接上干货! 主流: 目前的Linux操作系统主要应用于生产环境, 主流企业级Linux系统仍旧是RedHat或者CentOS. 免费: RedHat 和CentOS差别不大,CentOS是一 ...
- [java核心技术01]__继承与多态、重载与重写、抽象类与接口
前言 前面简单学习了面向对象的知识,知道了其两个重要的特性,继承与多态,今天就围绕着面向对象的这两个特性,将继承与多态及相关的几个几个定义重载与重写,抽象类与接口的相关知识具体学习一下. 类的继承 关 ...