一、权限实例

在阅读本文之前请先参考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或者Trueself.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 之 权限的更多相关文章

  1. Django REST framework认证权限和限制和频率

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  2. Django Rest Framework之权限

    基本代码结构 url.py: from django.conf.urls import url, include from app import views urlpatterns = [ url(r ...

  3. Django REST Framework 认证 - 权限 - 限制

    一. 认证 (你是谁?) REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 自定义Token认证 第一步 : 建表>>>> 定义一个 ...

  4. Django REST Framework之权限组件

    权限控制是如何实现的? 一般来说,先有认证才有权限,也就是用户登录后才能判断其权限,未登录用户给他一个默认权限. Django接收到一个请求,首先经过权限的检查,如果通过检查,拥有访问的权限,则予以放 ...

  5. Django REST framework认证权限和限制 源码分析

    1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...

  6. Django Rest Framework源码剖析(二)-----权限

    一.简介 在上一篇博客中已经介绍了django rest framework 对于认证的源码流程,以及实现过程,当用户经过认证之后下一步就是涉及到权限的问题.比如订单的业务只能VIP才能查看,所以这时 ...

  7. Django Rest framework 之 序列化

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  8. Django Rest framework 之 解析器

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

  9. Django Rest framework 之 版本

    RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...

随机推荐

  1. PMP:3.项目经理角色

    成员角色:整合指挥者 在团队中的职责:负终责 知识技能:综合技能&沟通   定义: 职能经理专注于对某个职能领域或业务部门的管理监督. 运营经理负责保证业务运营的高效性. 项目经理是由执行组织 ...

  2. spring boot开发笔记——mybatis

    概述   mybatis框架的优点,就不用多说了,今天这边干货主要讲mybatis的逆向工程,以及springboot的集成技巧,和分页的使用   因为在日常的开发中,当碰到特殊需求之类会手动写一下s ...

  3. Thinking in Java from Chapter 10

    From Thinking in Java 4th Edition 内部类 public class Parcel1 { class Contents { private int i = 11; pu ...

  4. 突然 不能f**q

    ss 突然访问不了,于是去查看ip是否被f,发现国outer 国inner 都通,不知道什么情况,后来把 系统代理模式 改为全局,发觉可以,又把他改为 pac模式,正常了.           记录一 ...

  5. ffmpeg命令: 删除视频中不需要的音频流

    1.ffprobe  gf.mkv 查看 2.ffmpeg  -i gf.mkv  -map 0:0 -map 0:2  -vcodec copy -acodec copy out.mkv 注: -m ...

  6. 2-3 用组件改写Todolist案例

     编写组件来改写2-2的Todolist案例

  7. [视频]K8飞刀 mysql注入点拿shell & UDF提权教程

    [视频]K8飞刀  mysql注入点拿shell & UDF提权教程 链接: https://pan.baidu.com/s/1a7u_uJNF6SReDbfVtAotIw 提取码: ka5m

  8. go微服务框架go-micro深度学习 rpc方法调用过程详解

    摘要: 上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取serv ...

  9. python之发送邮件~

    在之前的工作中,测试web界面产生的报告是自动使用python中发送邮件模块实现,在全部自动化测试完成之后,把报告自动发送给相关人员 其实在python中很好实现,一个是smtplib和mail俩个模 ...

  10. 一筐鸡蛋的lcm

    问题 一筐鸡蛋,一个一个取正好取完,两个两个取剩下一个,三个三个取正好取完,四个四个取剩下一个,五个五个取少一个,六个六个取剩下三个,七个七个取正好取完,八个八个取剩下一个,九个九个取正好取完,共多少 ...