DRF的限流组件(源码分析)
DRF限流组件(源码分析)
限流,限制用户访问频率,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷。
- 对于匿名用户,使用用户IP作为唯一标识。
- 对于登录用户,使用用户ID或名称作为唯一标识。
缓存={
用户标识:[12:33,12:32,12:31,12:30,12,] 1小时/5次 12:34 11:34
{
1. 配置缓存
# settings.py
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "qwe123",
}
}
}
2. 自定义限流类
# -*- encoding:utf-8 -*-
# @time: 2023/4/21 15:41
# @author: ifeng
from django.core.cache import cache as default_cache
from rest_framework import exceptions
from rest_framework import status
from rest_framework.throttling import SimpleRateThrottle
class ThrottledException(exceptions.APIException):
status_code = status.HTTP_429_TOO_MANY_REQUESTS
default_code = 'throttled'
class MyRateThrottle(SimpleRateThrottle):
cache = default_cache # 访问记录存放在django的缓存中(需设置缓存)
scope = 'user' # 构造缓存中的key
cache_format = 'throttle_%(scope)s_%(ident)s'
# 设置其他访问评率, 例如: 一分钟允许访问10次
# 其他: 's': 'sec', 'm': 'min', 'h': 'hour', 'd': 'day'
THROTTLE_RATES = {'user': '10/m'}
def get_cache_key(self, request, view):
if request.user:
ident = request.user.id
else:
ident = self.get_ident(request) # 获取请求用户IP(request中找请求头)
# throttle_u # throttle_user_11.11.11.11ser_2
return self.cache_format % {'scope': self.scope, 'ident': ident}
def throttle_failure(self):
wait = self.wait()
detail = {
'code': 1005,
'data': '访问频率限制',
'detail': '需要等待 %s s才能访问' % (int(wait))
}
raise ThrottledException(detail)
3. 使用限流类
- 局部配置(views)
class UserView(APIView):
throttle_classes = [MyRateThrottle, ] # 限流
- 全局配置(settings)
REST_FRAMEWORK = {
# 限流
"DEFAULT_THROTTLE_CLASSES": ["app01.throttle.MyRateThrottle", ],
"DEFAULT_THROTTLE_RATES": {
"user": "10/m",
# "xx":"100/h"
}
}
4. 多个限流类
本质,每个限流的类中都有一个 allow_request 方法,此方法内部可以有三种情况:
- 返回True,表示当前限流类允许访问,继续执行后续的限流类。
- 返回False,表示当前限流类不允许访问,继续执行后续的限流类。所有的限流类执行完毕后,读取所有不允许的限流,并计算还需等待的时间。
- 抛出异常,表示当前限流类不允许访问,后续限流类不再执行。
5. 源码分析
- 这是限流大体的执行逻辑, 后面将对allow_reqeust中具体分析

- allow_request()在自定义的类里面没定义, 所以我们到父类SimpleRateThrottle执行allow_request()方法

DRF的限流组件(源码分析)的更多相关文章
- alibaba sentinel限流组件 源码分析
如何使用? maven引入: <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>s ...
- 面试官:来谈谈限流-RateLimiter源码分析
RateLimiter有两个实现类:SmoothBursty和SmoothWarmingUp,其都是令牌桶算法的变种实现,区别在于SmoothBursty加令牌的速度是恒定的,而SmoothWarmi ...
- Django框架之drf:8、断点调试,权限、认证、频率组件源码分析,基于APIView编写分页,异常处理
Django框架之drf 一.断点调式使用 指,在我们编写代码的时候,程序运行出现报错是无可避免的,当程序 出现报错时,我们需要找到出现报错的代码进行修改,如果时简短的代码很容易就可以找到报错位置 ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
- element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
- ceph-csi组件源码分析(1)-组件介绍与部署yaml分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi组件源码分析(1)-组件介绍与部署yaml分析 基于tag v3.0.0 ht ...
- 开源MyBatisGenerator组件源码分析
开源MyBatisGenerator组件源码分析 看源码前,先了解Generator能做什么? MyBatisGenerator是用来生成mybatis的Mapper接口和xml文件的工具,提供多种启 ...
- element-ui button组件 radio组件源码分析整理笔记(一)
Button组件 button.vue <template> <button class="el-button" @click="handleClick ...
- element-ui MessageBox组件源码分析整理笔记(十二)
MessageBox组件源码,有添加部分注释 main.vue <template> <transition name="msgbox-fade"> < ...
- Django REST framework —— 权限组件源码分析
在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 class ShoppingCarView(ViewSetMix ...
随机推荐
- POE供电及PD的功率分级
POE供电标准有IEEE802.3af和IEEE802.3at 802.3af,PSE最高提供15.5W的功率而PD端则为12.95W: 802.3at,PSE最高提供30W的功率而PD端则为25W: ...
- 磊磊零基础打卡算法:day16 c++ Trie树
5.19 Trie树: 用处:快速的查找和高效存储字符串集合的数据结构. 类似如此的查找,存储 其简单的两个操作:插入和删除 插入: void insert(char str[]) { int p; ...
- ASP.NET WEBAPI oken验证
看了下网上关于.net webAPI 的案例全是坑 验证成功了不被微信服务器接收 微信客服有找不到,提问也没人回 自己测试好几个小时 终于发现返回结果只要个string 双引号都不用加 public ...
- 中国移动光猫(吉比特h2-3S)超级用户名与密码
超级用户名 CMCCAdmin 密码 aDm8H%MdA
- 2020.6.6OO学期末总结
0.前言 本次博客是对整个java及oo学习情况的一个概略性总结,目的在于反思这半年来的学习情况和实际感受,和具体学习方面的理解和问题. 1.作业过程总结 看着自己一个学期做的所有作业,我想起的是总是 ...
- Svn安装客户端鼠标右键报错SendRpt.exe not found
kill 掉 重启资源管理器就好了
- keycloak(转载)
# 生成KEYSTORE.JKS keytool -genkeypair -alias keycloak.me -keyalg RSA -keystore keycloak.jks -validity ...
- vue 数组修改 页面无法刷新
saveData: { current: 1, records:[] , total:0}, countSaveMoney:{ bidSuccessMoney:0, saveMoney:0},页面上有 ...
- 微信小程序分享出去的页面再点进来,如何取值并且在新用户未授权的情况下,授权后跳到当前页面
1.如何点击分享的页面进来,授权后跳转到当前页面 可以在授权成功后,将openid.头像.昵称入库成功之后,标记一下,及getStorageSync // 通过code获取openid getUser ...
- Less-4 报错注入
补坑:报错注入 当我们 union 无法注入的时候,可以使用报错注入,这里我们有三种报错注入,xpth语法错误和count()+rand()+floor()+group by重复组建错误 extrac ...