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 结构 ...
随机推荐
- 阿里云Kubernetes服务上使用Tekton完成应用发布初体验
Tekton 是一个功能强大且灵活的 Kubernetes 原生开源框架,用于创建持续集成和交付(CI/CD)系统.通过抽象底层实现细节,用户可以跨多云平台和本地系统进行构建.测试和部署. 本文是基于 ...
- 【[Offer收割]编程练习赛9 C】三等分
[题目链接]:http://hihocoder.com/problemset/problem/1479 [题意] . [题解] 首先算出所有节点的权值的和val; 然后如果val%3!=0则直接输出0 ...
- bzoj 4386: [POI2015]Wycieczki
bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...
- mysql数据库之多表查询
准备 ...
- Android Listview中Button按钮点击事件冲突解决办法
今天做项目时,ListView中含有了Button组件,心里一早就知道肯定会有冲突,因为以前就遇到过,并解决过,可惜当时没有记录下来. 今天在做的时候,继续被这个问题郁闷了一把,后来解决后,赶紧来记录 ...
- ccf-201403-3有趣的命令行
傻逼题,要是考试只能得0分.. 提供几组傻逼数据,这要是在真实的生活中一定是错的... 还是要好好读题吧,全凭自己的感觉就得0分 albw:x 4 ls -a docu Case 1: -a ls - ...
- Python--day72--ajax简介
ajax的基本结构: <script> $("#b1").on("click", function () { $.ajax({ url: " ...
- Linux下yum安装Redis
检验是否有yum源: [root@localhost ~]# yum install redis 显示没有软件包Redis,安装epel仓库(提供一些RHEL/CentOS默认不提供的软件包). [r ...
- dotnet 设计规范 · 抽象定义
严格来说,只有一个类被其他的类继承,那么这个类就是基类.在很多时候,基类的定义是提供足够的抽象和通用方法和属性.默认实现.在继承关系中,基类定义在上层抽象和底层自定义之间. 他们充当抽象实现的实现帮助 ...
- vue echarts引用
<template> <!--为echarts准备一个具备大小的容器dom--> <div id="main" style="width: ...