DRF-访问频率配置(节流)

简介: 访问频率控制(节流)我们可以先编写一个类class VisitThrottle(object): def allow_request(self, request, view): return True # False表...

访问频率控制(节流)

  • 我们可以先编写一个类
class VisitThrottle(object):
    def allow_request(self, request, view):
        return True  # False表示访问频率太高被限制
    def wait(self):
        return None    
AI 代码解读
img_7f41070780659b927c02a7bf2429cb85.png
微信截图_20190112111427
  • postman校验
img_dba2f2d4b99d8e4264d1673bb9a35c18.png
微信截图_20190112111522
img_64c8a05c0d0a1b395082e8e5028ca654.png
微信截图_20190112111555
  • 获取用户ip
class VisitThrottle(object):
    def allow_request(self, request, view):
        # 1. 获取用户ip
        remote_addr = request._request.META.get("REMOTE_ADDR")
        #print(remote_addr)

        ...
AI 代码解读
  • 添加访问记录
import time

# 存放访问记录(一般放数据库或者缓存中)
VISIT_RECORD = {}


class VisitThrottle(object):
    def allow_request(self, request, view):
        # 1. 获取用户ip
        remote_addr = request._request.META.get("REMOTE_ADDR")
        # print(remote_addr)
        # 2. 添加到访问记录中
        ctime = time.time()
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime, ]
            return True
        return False  # False表示访问频率太高被限制

    def wait(self):
        return None
AI 代码解读
img_52b5bfae5276a7e6c96ae90f2f441d07.png
微信截图_20190112112710
  • 两种情况,之前说的是第一种,当用户没有访问的时候的情况,记录用户的访问记录的列表里面没有用户访问,但是如果用户已经访问,而我们需求是1分钟内只能访问3次,我们需要改进代码
class VisitThrottle(object):
    def allow_request(self, request, view):
        # 1. 获取用户ip
        remote_addr = request._request.META.get("REMOTE_ADDR")
        # print(remote_addr)
        # 2. 添加到访问记录中
        ctime = time.time()
        # 当VISIT_RECORD中没有这个记录,可以直接访问,添加一个记录
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime, ]
            return True
        history = VISIT_RECORD.get(remote_addr)
        # 拿到最后历史记录里面的最后一个时间,如果最后一个时间小于当前时间-60
        while history and history[-1] < ctime - 60:
            history.pop()
        if len(history) < 3:
            history.insert(0,ctime)
            return True

        return False  # False表示访问频率太高被限制

    def wait(self):
        return None
AI 代码解读
img_590d7cdbcd4bfd58a8af5c8f219410b6.png
微信截图_20190112113607
  • postman校验
img_f1fc5411de3221ba941da2e6cd62d7c5.png
微信截图_20190112113637
  • wait返回的值是一个提示,表示多少秒以后可以访问
    def wait(self):
        return 10 # 写死了10秒
AI 代码解读
img_9ea9348c86b0e9d3c4d25b1e173a5d14.png
微信截图_20190112120909
  • 在wait里面拿到访问记录
img_6925193284c7bdfe22e6b806bff8377f.png
微信截图_20190112121324
    def wait(self):
        """
        还需要等多少秒可以访问
        :return:
        """
        ctime = time.time()

        return 60 - (ctime - self.history[-1])
AI 代码解读

源码流程

内置控制频率的类

from rest_framework.throttling import BaseThrottle


class VisitThrottle(BaseThrottle):

    def __init__(self):
        self.history = None

    def allow_request(self, request, view):
        # 1. 获取用户ip
        remote_addr = request._request.META.get("REMOTE_ADDR")
        # print(remote_addr)
        # 2. 添加到访问记录中
        ctime = time.time()
        # 当VISIT_RECORD中没有这个记录,可以直接访问,添加一个记录
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime, ]
            return True
        history = VISIT_RECORD.get(remote_addr)
        self.history = history
        # 拿到最后历史记录里面的最后一个时间,如果最后一个时间小于当前时间-60
        while history and history[-1] < ctime - 60:
            history.pop()
        if len(history) < 3:
            history.insert(0, ctime)
            return True

        return False  # False表示访问频率太高被限制

    def wait(self):
        """
        还需要等多少秒可以访问
        :return:
        """
        ctime = time.time()
        return 60 - (ctime - self.history[-1])
AI 代码解读
img_a413669ae810c094d4bfd3cff344c11b.png
微信截图_20190112141225
  • 在SimpleRateThrottle里面
img_de72bfdc3d4c91a253133ed616c8ce4f.png
微信截图_20190112141531
  • get_rate方法
img_40f04ea0d335b64d62b89d68f50c7c71.png
微信截图_20190112141649
  • get_rate方法返回值读取配置文件
img_ee32598c99b4ff1eee9459f971166308.png
微信截图_20190112141713
  • 在我们自己继承的类里面写scpoe
img_263d6697eb0bf4dfb88dfdf5a2b2d1a0.png
微信截图_20190112142138
  • settings配置
# 跟rest_有关的配置
REST_FRAMEWORK = {
    # "DEFAULT_AUTHENTICATION_CLASSES": ["myutils.auth.MyAuthtication"],
    "UNAUTHENTICATED_USER": lambda: "匿名用户哈哈",
    # "DEFAULT_PERMISSION_CLASSES": ["myutils.permission.MyPermission"],
    "DEFAULT_THROTTLE_RATES": {
        "myscope": '3/m'
    }

}
AI 代码解读
img_e8978b6d7aacf6ab44ca324599bdbe89.png
微信截图_20190112142416
  • 我们设置的频率在源码里面传递
img_318d431d3b49201e12d829677e8b2492.png
微信截图_20190112142521
  • 3/m源码 m表示60
img_09be3d9128bb2565a125fbcbcfa21116.png
微信截图_20190112142816
  • 回到构造函数
    def __init__(self):
        # 在构造方法里面,通过反射调用rate
        if not getattr(self, 'rate', None):
            # "3/m"
            self.rate = self.get_rate()
        #   3次 self.num_requests    60秒  self.duration
        self.num_requests, self.duration = self.parse_rate(self.rate)
AI 代码解读
  • 内部的allow_request方法
img_f6f476654c065dd759e3d37b1dc914b0.png
微信截图_20190112143207
  • 使用ip作为我们的标识
class VisitThrottle(SimpleRateThrottle):
    scope = "myscope"

    def get_cache_key(self, request, view):
        return self.get_ident(request)
AI 代码解读
  • allow_request
    def allow_request(self, request, view):
        """
        Implement the check to see if the request should be throttled.

        On success calls `throttle_success`.
        On failure calls `throttle_failure`.
        """
        if self.rate is None:
            return True
        # 方法缓存里面
        self.key = self.get_cache_key(request, view)
        if self.key is None:
            return True
        # 去缓存里面拿到所有记录
        self.history = self.cache.get(self.key, [])
        # 获取当前时间
        self.now = self.timer()

        # Drop any requests from the history which have now passed the
        # throttle duration
        while self.history and self.history[-1] <= self.now - self.duration:
            self.history.pop()
        if len(self.history) >= self.num_requests:
            # 失败
            return self.throttle_failure()
        # 成功
        return self.throttle_success()
AI 代码解读
  • settings配置
# 跟rest_有关的配置
REST_FRAMEWORK = {
    # "DEFAULT_AUTHENTICATION_CLASSES": ["myutils.auth.MyAuthtication"],
    "UNAUTHENTICATED_USER": lambda: "匿名用户哈哈",
    # "DEFAULT_PERMISSION_CLASSES": ["myutils.permission.MyPermission"],
    "DEFAULT_THROTTLE_CLASSES": ['myutils.throttle.VisitThrottle'],
    "DEFAULT_THROTTLE_RATES": {
        "myscope": '3/m'
    }

}

AI 代码解读

对当前用户做限流操作

class UserThrottle(SimpleRateThrottle):
    scope = "user_scope"

    def get_cache_key(self, request, view):
        return request.user.username
AI 代码解读
  • settings配置
# 跟rest_有关的配置
REST_FRAMEWORK = {
    # "DEFAULT_AUTHENTICATION_CLASSES": ["myutils.auth.MyAuthtication"],
    "UNAUTHENTICATED_USER": lambda: "匿名用户哈哈",
    # "DEFAULT_PERMISSION_CLASSES": ["myutils.permission.MyPermission"],
    "DEFAULT_THROTTLE_CLASSES": ['myutils.throttle.VisitThrottle'],
    "DEFAULT_THROTTLE_RATES": {
        "myscope": '3/m',  # 匿名用户一分钟访问3次
        "user_scope": "8/m"  # 登陆用户一分钟访问8次
    }

}
AI 代码解读
img_ed1a67a99d4acc4982a9f54e7a548d20.png
微信截图_20190112163216
相关文章
nginx配置http和https共存
server { listen 80; listen 443 ssl; server_name localhost;        #ssl on; ssl_certificate /usr/local/Tengine/sslcrt/linuxyan.
4972 0
软件安装(四):Pycharm安装详细教程
本文提供了一个详细的PyCharm安装教程,包括下载、安装和使用步骤,特别强调了在Windows环境下安装时不要选择关联.py文件的选项,并说明了如何配置系统环境变量Path以及激活账号密码。
298 1
软件安装(四):Pycharm安装详细教程
移动应用开发的艺术与实践:从新手到专家
【10月更文挑战第2天】在数字化时代,移动应用已成为连接用户与服务的桥梁。本文旨在为初学者和资深开发者提供一个全面的指南,涵盖从基础概念、开发环境搭建、核心编程技能,到高级架构设计和性能优化的全方位知识。通过深入浅出的讲解和实战案例分析,我们将一起探索移动应用开发的奥秘,解锁打造高效、用户友好应用的关键策略。无论你是初涉移动开发领域,还是希望提升现有技能,这篇文章都将是你的宝贵资源。
React 模态框 Modal 组件详解
【10月更文挑战第27天】本文介绍了如何在 React 中实现一个功能完善的模态框组件。从基础概念入手,逐步讲解了简单的模态框实现、CSS 样式、传递子组件、键盘事件处理等高级功能。同时,还探讨了常见问题及易错点,如背景点击关闭、键盘事件冲突和动画效果。通过本文,读者可以全面了解 React 模态框组件的实现细节。
535 0
技术下午茶:产品经理是如何工作的?如何才算一份好的需求文档?如何设计一个简单的列表,它应该具备哪些基本功能?
技术下午茶:产品经理是如何工作的?如何才算一份好的需求文档?如何设计一个简单的列表,它应该具备哪些基本功能?
172 1
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
240 3
怎么关闭Windows安全中心?
Windows安全中心是Windows的防护组件,负责抵挡病毒和威胁。关闭它可能增加安全风险,但若必须,可遵循以下方法:通过设置-&gt;更新和安全-&gt;病毒和威胁防护管理设置关闭实时保护;使用组策略编辑器禁用“隐藏病毒和威胁防护区域”;或在注册表编辑器中创建DisableAntiSpyware DWORD并设值为1。关闭前务必安装其他安全软件并保持系统更新。
怎么关闭Windows安全中心?
ArcGIS面要素最小外接矩形、外接圆的绘制方法
ArcGIS面要素最小外接矩形、外接圆的绘制方法
320 1
『Charles数据抓包功攻略』| 如何使用Charles进行数据抓包与分析?
『Charles数据抓包功攻略』| 如何使用Charles进行数据抓包与分析?
532 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问