DRF的限流组件(源码分析)

news2025/1/17 17:52:29

限流,限制用户访问频率,例如:用户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. 源码分析

  1. 这是限流大体的执行逻辑, 后面将对allow_reqeust中具体分析

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/884897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图文结合丨带你轻松玩转MySQL Shell for GreatSQL

一、引言 1.1 什么是MySQL Shell ? MySQL Shell 是 MySQL 的一个高级客户端和代码编辑器,是第二代 MySQL 客户端。第一代 MySQL 客户端即我们常用的 MySQL 。除了提供类似于 MySQL 的 SQL 功能外,MySQL Shell 还提供 JavaScript 和 Python 脚本功能&a…

免费开源服务器资源监控系统grafana+prometheus+node_exporter

有项目做测试的时候需要查询服务器资源利用情况,自己又没写相应的模块,此时就需要一套好用的资源监控系统,,咨询了运维人员给推荐了一套,装完后真的很好用。 就是grafanaprometheusnode_exporter(linux&am…

Python项目实战:将3D灰度图像转换为3D彩色图像

文章目录 (3D-GRAY) to (3D-RGB):使用颜色映射的方式,将灰度值映射到彩色空间中的特定颜色。一、多维数组:10x12x14(1)channel重复:在RGB中,将【灰度图】分别赋值给【R/G/B图】,显示…

NPM与外部服务的集成(下)

目录 1、撤消访问令牌 2、在CI/CD工作流中使用私有包 2.1 创建新的访问令牌 持续整合 持续部署 交互式工作流 CIDR白名单 2.2 将令牌设置为CI/CD服务器上的环境变量 2.3 创建并签入特定于项目的.npmrc文件 2.4 令牌安全 3、Docker和私有模块 3.1 背景:运…

类加载器与反射

类加载器,反射 1.类加载器 1.1类加载器【理解】 作用 负责将.class文件(存储的物理文件)加载在到内存中 1.2类加载的过程【理解】 类加载时机 创建类的实例(对象)调用类的类方法访问类或者接口的类变量&#xff0…

如何做好项目进度管理,项目经理可以这样做

项目追踪是通过把控项目的进度、成员的任务完成情况,以及项目计划进展等方面来进行的。项目经理在进行项目进度跟踪时,主要从以下三个方面进行: 1、制定并完善项目计划 项目经理使用进度猫等工具制定项目计划,通过甘特图对项目…

将Excel表格复制到Word文档中

目录 方式1:粘贴 -> 保留源格式(CtrlV的默认行为)参考文献 方式1:粘贴 -> 保留源格式(CtrlV的默认行为) 保留源格式是Word在粘贴来自其他程序内容时的默认行为(直接CtrlV)。如…

解决右键打印html只能识别1页的问题

hello,大家好久不见,昨天在开发中遇到了一个问题,就是在自己开发的网页中右键-->打印,由于页面内容过多,打印出来的内容只被识别到一页。 针对这一问题,查阅了好多资料最终解决啦。 1.问题重现 大家可以看到这个是我们开发的页面,公司需要…

.netcore grpc的proto文件字段详解

一、.proto文件字段概述 grpc的接口传输参数都是根据.proto文件约定的字段格式进行传输的grpc提供了多种类型字段;主要包括标量值类型(基础类型)、日期时间、可为null类型、字节、列表、字典、Any类型(任意类型)、One…

Python文件操作与输入输出:从基础到高级应用

文章目录 🍀引言🍀文件操作基础🍀上下文管理器与文件自动关闭🍀文件的迭代与逐行读取🍀文件的其他常见操作🍀输入输出基础🍀 文件输入输出🍀格式化输出🍀高级文件操作&am…

6---列表

一、有序列表 在文本前面添加数字英文句点(.)空格可以构成有序列表。如下表,最终生成的列表前面的编号和前面的数字没有绝对关系,总是从第一个数字开始依次增加。(和C的枚举有一点点类似) 注意:…

解决keep-alive缓存失效问题【必看!!!】

最近正在使用Vue3TsPinia重构后台管理项目&#xff0c;在写到路由缓存时&#xff0c;发现怎么都缓存不了&#xff0c;后来才找到了原因&#xff1a; Vue3中的setup语法糖中的name命名无效 即&#xff1a;如果你是按如下写组件的name&#xff0c;是不起作用的 <script nam…

ARM-M0内核MCU,内置24bit ADC,采样率4KSPS,传感器、电子秤、体脂秤专用,国产IC

ARM-M0内核MCU 内置24bit ADC &#xff0c;采样率4KSPS flash 64KB&#xff0c;SRAM 32KB 适用于传感器&#xff0c;电子秤&#xff0c;体脂秤等等

报名开启 | 2023RflySim暑期学校 : 基于RflySim平台飞控底层算法开发专题培训(第二期)

飞思实验室“基于RflySim平台飞控底层算法开发”系列专题培训第二期开启报名了&#xff01;专题培训由戴训华副教授以及飞思实验室学生&工程师团队主讲&#xff0c;采用“线上线下”集中授课形式&#xff0c;培训时间为8月28日-9月3日&#xff1b;课程内容以RflySim平台介绍…

vite+vue3初始化项目

node环境 14.18&#xff0c;16。最好是16 初始化项目 执行 npm create vuelatest 就是基于vite的命令&#xff0c;执行后会出现以下选择&#xff1a; 目录结构介绍 基本和vue2一个意思 vite.config.js文件如同vue2中的vue.config.js文件&#xff0c;用于配置项目的 安装…

C语言入门 Day_5 四则运算

目录 前言 1.四则运算 2.其他运算 3.易错点 4.思维导图 前言 图为世界上第一台通用计算机ENIAC,于1946年2月14日在美国宾夕法尼亚大学诞生。发明人是美国人莫克利&#xff08;JohnW.Mauchly&#xff09;和艾克特&#xff08;J.PresperEckert&#xff09;。 计算机的最开始…

应用在汽车前照灯系统中的环境光传感芯片

为了保证行车照明的安全性和方便性&#xff0c;减轻驾驶员的劳动强度。近年来&#xff0c;出现了许多新的照明控制系统&#xff0c;例如用于日间驾驶的自动照明系统、光束调节系统、延迟控制等。尤其是汽车自适应前照灯系统&#xff0c;它是一种能够自动改变两种以上的光型以适…

驱动压力P阀10Ω/流量Q阀40Ω比例阀放大器

模块式比例放大器用于控制比例压力流量阀&#xff0c;可驱动PQ比例阀或驱动两路独立控制比例阀&#xff0c;数码管显示现场可设置不同参数&#xff0c;带故障报警提示&#xff0c;DIN35mm导轨安装&#xff0c;24VDC供电&#xff1b;输入指令信号可选0-5V&#xff0c;0-10V&…

线切割数控系统 CAM 功能开发

在第三章我们完成了 Windows CE 系统的的内核定制与软件移植&#xff0c;本实验室开 发的 CAWEP 软件实现了从图形绘制、编辑到运动仿真、代码输出等功能&#xff0c;并未真 正意义上实现线切割机床的控制&#xff0c;本章我们在已有软件的基础上&#xff0c;进行研究与开…

DFT笔记 DC/AC mode与Func

DFT scan可以分为DC和AC两种&#xff0c;区别如下图 DC模式需要ate测试机台提供test clock时钟&#xff08;最快100M&#xff09;&#xff0c;DFT工程师需要升级普通reg变成带si和so&#xff0c;se pin的reg&#xff0c;并插入扫描链&#xff08;scan chain&#xff09;&#x…