三大认证

流程

  • 由于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)
  1. 认证组件
  • 请求未携带token ==> 游客
  • 请求携带token
    • token认证通过 ==> 合法用户
    • token认证未通过 ==> 非法用户
  1. 权限组件
  • 游客权限
  • 登录用户权限
  1. 频率组件
  • 限制
  • 不限制

认证组件

  1. DRF认证类的默认配置
# rest_framework/settings.py
'DEFAULT_AUTHENTICATION_CLASSES': [
# 默认采用的session认证
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
  1. 自定义认证类
    1. 继承BaseAuthentication
    2. 重写authenticate方法
    3. 方法体
      1. 从请求头HTTP_AUTHORIZATION中拿token
      2. 没有token返回None, 游客
      3. 有token, 校验不通过, 抛AuthenticationFailed异常, 非法用户
      4. 有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
  1. 全局配置认证类
# settings.py
REST_FRAMEWORK = {
# 全局配置认证类
'DEFAULT_AUTHENTICATION_CLASSES': [
'api.authentications.MyAuthentication',
'rest_framework.authentication.BasicAuthentication',
]
}

权限组件

  1. 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:游客有读权限,登录用户有全权限
"""
  1. 自定义权限类
    1. 继承BasePermission
    2. 重写has_permission方法
    3. 方法体
      1. 根据实际需求设置条件
      2. 返回True, 代表有权限
      3. 返回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
  1. 局部配置权限类
# 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
})

频率组件

  1. 自定义频率组件

    1. 继承SimpleRateThrottle
    2. 设置 scope='xxx', xxx 对应的是在settings.py设置的频率 'xxx': '1/min'
    3. 重写get_cache_key方法
    4. 方法体:
      1. 返回None, 不做限制
      2. 返回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的更多相关文章

  1. $Django importlib与dir知识,手写配置文件, 配置查找顺序 drf分页器&drf版本控制

    1  importlib与dir知识 # importlib简介动态导入字符串模块 # 常规导入 from ss.aa import b from ss import a print(b,type(b ...

  2. python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)

    考试第二部分:MySQL数据库 6.  MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7.   MySQL中va ...

  3. python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  4. DRF的认证、权限 和 限制

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

  5. VUE+DRF系列

    vue基础系列 001 路飞学诚项目简介 002 Vue简介 003 Vue引入 004 文本指令 005 事件指令 006 斗篷指令 007 属性指令 008 表单指令 009 条件指令 010 路 ...

  6. drf源码剖析系列(系列目录)

    drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...

  7. 067.Python框架Django之DRF视图类

    一 关于视图类的一下概念 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. ...

  8. iOS系列 基础篇 08 文本与键盘

    iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...

  9. javaEE基础08

    javaEE基础08 一.继承 特点:继承父类的属性和方法,单继承(多继承) 特性:方法的复写(重写) 比如:人可以养狗 人------>狗:整体和部分(拥有)关系 关键字:extends 结构 ...

随机推荐

  1. Card Hand Sorting 二进制枚举暴力

    这个题其实由于只有4种花色的,那么每种花色排列的顺序,也不过是4!种,然后对于每种花色内部到底是升序还是降序,其实也可以直接暴力,一共也就4!*2^4种情况,然后直接进行排序就可以了,但是我们如何计算 ...

  2. Python语言的缺点

  3. 深入Java线程管理(三):线程同步

    一. 引入同步: 有一个很经典的案例,即银行取款问题.我们可以先看下银行取款的基本流程: 1)用户输入账户.密码,系统判断用户的账户.密码是否匹配. 2)用户输入取款金额. 3)系统判断账户金额是否大 ...

  4. H3C 帧中继协议特点

  5. java什么是跨平台性?原理是什么?

    所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行. 实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行 ...

  6. Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例

    从某种意义上说,服务提供者有点类似HTTP控制器,HTTP控制器用于为相关路由注册提供统一管理,而服务提供者用于为相关服务容器提供统一绑定场所,此外服务提供者还可以做一些初始化启动操作.Laravel ...

  7. Python--day40--主线程和子线程代码讲解

    1,最简单的线程例子: 2,多线程并发: import time from threading import Thread #多线程并发 def func(n): time.sleep(1) prin ...

  8. Python--day40线程理论

    1,进程:

  9. 【React】 百度地图API

    百度地图 开发文档 :http://lbsyun.baidu.com/index.php?title=jspopular 调用接口 需要 内置加载一个 百度api文件    使用自己的ak  申请一个 ...

  10. P1102 走迷宫二

    题目描述 大魔王抓住了爱丽丝,将她丢进了一口枯井中,并堵住了井口. 爱丽丝在井底发现了一张地图,他发现他现在身处一个迷宫当中,从地图中可以发现,迷宫是一个N*M的矩形,爱丽丝身处迷宫的左上角,唯一的出 ...