DRF 08
三大认证
流程

- 由于DRF中, 所有的视图类都要直接和间接继承APIView类, 也只有APIView类中才有dispatch方法, 所以所有的请求都要经过三大认证, 认证通过后执行相应请求的视图函数
def dispatch(self, request, *args, **kwargs):
"..."
try:
# 三大认证
self.initial(request, *args, **kwargs)
"..."
except Exception as exc:
# 异常处理
response = self.handle_exception(exc)
def initial(self, request, *args, **kwargs):
"..."
# 认证
self.perform_authentication(request)
# 权限
self.check_permissions(request)
# 频率
self.check_throttles(request)
认证组件
- 请求未携带token ==> 游客
- 请求携带token
- token认证通过 ==> 合法用户
- token认证未通过 ==> 非法用户
权限组件
- 游客权限
- 登录用户权限
频率组件
- 限制
- 不限制
认证组件
DRF认证类的默认配置
# rest_framework/settings.py
'DEFAULT_AUTHENTICATION_CLASSES': [
# 默认采用的session认证
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
自定义认证类
- 继承BaseAuthentication
- 重写authenticate方法
- 方法体
- 从请求头HTTP_AUTHORIZATION中拿token
- 没有token返回None, 游客
- 有token, 校验不通过, 抛AuthenticationFailed异常, 非法用户
- 有token, 校验通过, 返回(user, token), 合法用户
# authentications.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
# 自定义认证类继承BaseAuthentication
class MyAuthentication(BaseAuthentication):
"""
1.从请求中获取token(一般是HTTP_AUTHORIZATION)
2.token为None, 返回None, ==> 游客
3.token不为None
认证失败, raise AuthenticationFailed(''), ==> 非法用户
认证通过, 返回(user, token)或者(user, None), ==> 合法用户
"""
def authenticate(self, request):
pass
全局配置认证类
# settings.py
REST_FRAMEWORK = {
# 全局配置认证类
'DEFAULT_AUTHENTICATION_CLASSES': [
'api.authentications.MyAuthentication',
'rest_framework.authentication.BasicAuthentication',
]
}
权限组件
DRF权限类的默认配置
# rest_framework/settings.py
'DEFAULT_PERMISSION_CLASSES': [
# 默认不做权限限制
'rest_framework.permissions.AllowAny',
],
class AllowAny(BasePermission):
def has_permission(self, request, view):
return True
"""
DRF默认提供的些权限类:
AllowAny:游客和登录用户有全权限
IsAuthenticated:只有登录用户有全权限
IsAdminUser:只有后台用户(admin用户)有全权限
IsAuthenticatedOrReadOnly:游客有读权限,登录用户有全权限
"""
自定义权限类
- 继承BasePermission
- 重写has_permission方法
- 方法体
- 根据实际需求设置条件
- 返回True, 代表有权限
- 返回False, 代表无权限
# permissions.py
from rest_framework.permissions import BasePermission
# vip用户权限
class VipPermission(BasePermission):
def has_permission(self, request, view):
for group in request.user.groups.all():
if group.name.lower() == 'vip':
return True
return False
局部配置权限类
# views.py
# 只有vip用户才能进行单查
class UserViewSet(ViewSet):
# 局部配置权限类
permission_classes = [permissions.VipPermission]
def retrieve(self, request, *args, **kwargs):
return APIResponse(results={
'username': request.user.username,
'email': request.user.email,
'mobile': request.user.mobile
})
频率组件
自定义频率组件
- 继承SimpleRateThrottle
- 设置
scope='xxx',xxx对应的是在settings.py设置的频率'xxx': '1/min' - 重写get_cache_key方法
- 方法体:
- 返回None, 不做限制
- 返回self.cache_format, 有频率限行
# throttles.py
from rest_framework.throttling import SimpleRateThrottle
# 自定义频率限制类: 按照手机号限行
class MobileRateThrottle(SimpleRateThrottle):
scope = 'mobile'
def get_cache_key(self, request, view):
# 匿名用户和没有手机号的不做限制
if not request.user.is_authenticated or not request.user.mobile:
return None # 反正None就是不做限制
return self.cache_format % {
'scope': self.scope,
'ident': request.user.mobile
}
# settings.py
REST_FRAMEWORK = {
# 频率类一般是局部配置, 但是频率调节在settings.py中配置
'DEFAULT_THROTTLE_RATES': {
'user': '5/min',
'anon': '3/min',
'mobile': '1/min'
},
}
自定义token的签发
- 要实现多方式登录, 一定要自定义token的签发
class LoginModelSerializer(serializers.ModelSerializer):
username = serializers.CharField(max_length=12, min_length=3)
password = serializers.CharField(min_length=6)
class Meta:
model = models.User
fields = ('username', 'password')
# 全局钩子完成token签发
def validate(self, attrs):
# 1.获取user对象
user = self._validate_user(attrs)
# 2.获取payload
payload = jwt_payload_handler(user)
# 3.获取token
token = jwt_encode_handler(payload)
# 4.将user和token保存到serializer对象中, 以便在视图类中使用
self.content = {
'user': user,
'token': token
}
return attrs
# 多方式登录
def _validate_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
# 邮箱
if re.match(r'.*@.*', username):
user = models.User.objects.filter(email=username).first()
# 手机号
elif re.match(r'1[3-9][0-9]{9}$', username):
user = models.User.objects.filter(mobile=username).first()
# 用户名
else:
user = models.User.objects.filter(username=username).first()
if not user or not user.check_password(password):
raise serializers.ValidationError({'msg': '用户名或密码错误'})
return user
DRF 08的更多相关文章
- $Django importlib与dir知识,手写配置文件, 配置查找顺序 drf分页器&drf版本控制
1 importlib与dir知识 # importlib简介动态导入字符串模块 # 常规导入 from ss.aa import b from ss import a print(b,type(b ...
- python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)
考试第二部分:MySQL数据库 6. MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7. MySQL中va ...
- python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- DRF的认证、权限 和 限制
一.概述 认证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不能访问某个接 ...
- VUE+DRF系列
vue基础系列 001 路飞学诚项目简介 002 Vue简介 003 Vue引入 004 文本指令 005 事件指令 006 斗篷指令 007 属性指令 008 表单指令 009 条件指令 010 路 ...
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 067.Python框架Django之DRF视图类
一 关于视图类的一下概念 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. ...
- iOS系列 基础篇 08 文本与键盘
iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...
- javaEE基础08
javaEE基础08 一.继承 特点:继承父类的属性和方法,单继承(多继承) 特性:方法的复写(重写) 比如:人可以养狗 人------>狗:整体和部分(拥有)关系 关键字:extends 结构 ...
随机推荐
- Liunx vi/vim 2
移动光标的方法 H 光标移动到这个屏幕的最上方那一行的第一个字符 M 光标移动到这个屏幕的中央那一行的第一个字符 L 光标移动到这个屏幕的最下方那一行的第一个字符 G 移动到这个档案的最后一行(常用 ...
- Python中进制转换函数的使用
Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...
- 模块化Vs组件化
模块化&组件化 原因 图解 模块化Module 概念 使用 目的 依赖 架构定位 内容:组件内的Script 组件化 概念 使用 目的:复用,解耦 依赖 架构定位 内容:template.st ...
- Activiti快速入门项目-kft-activiti-demo
1.项目简介 1.1 项目信息 本项目旨在让Activiti初学者可以快速入门,使用工作流里面的请假流程作为Activiti企业实战的Hello World. 简单通过这个实例说明如何结合流程与业务, ...
- 使用 Laravel-Excel 进行 CSV/EXCEL 文件读写
https://blog.csdn.net/yiluohan0307/article/details/80229978 http://www.ptbird.cn/laravel-excel-csv.h ...
- 手写call,apply方法实现
call Function.prototype.myCall = function(){ var object = arguments[0]; var arr = []; for(var i = 1; ...
- Element-ui学习笔记3--Form表单(三)
InputNumber <el-input-number v-model="num" @change="handleChange" :min=" ...
- axis2 wsdl2java工具
wsdl2java工具使用方法描述: C:\Users\Administrator>wsdl2java -h Using AXIS2_HOME: E:\Apache_Projects\axis2 ...
- Python--day46--分组(看了别人博客掌握的)
原文链接:https://www.cnblogs.com/snsdzjlz320/p/5738226.html group by group by + group_concat() group by ...
- 如何解决vue项目中 scss 不支持 scoped 的 /deep/ 穿透写法
如何解决vue项目中 scss 不支持 scoped 的 /deep/ 穿透写法 用过vue的人估计都用过scoped样式属性,但有时候需要穿透样式,啥办? 很多资料都说用>>> 或 ...