首页 > 其他分享 >7.drf-限流

7.drf-限流

时间:2023-02-16 22:45:06浏览次数:387  
标签:ident self cache rest 限流 import drf

限流就是限制用户的访问频率,如每分钟的操作的次数不超过3次等

  • 对于匿名用户,使用用户IP作为唯一标识

  • 对于登录用户,则使用用户的ID作为唯一标识

1.限流的机制

DRF中维护了一个缓存,以用户的唯一标识作为键,一个列表为值,存放着当前用户访问的时间戳。
当用户再次请求的时候,会根据用户唯一标识去缓存中找到列表,判断用户的访问次数是否超过限制,超出限制则禁止访问

在实际开发中,最常用的还是redis

2.配置redis

在setting.py中配置缓存为redis

pip install django-redis
复制代码
CASHES = {
    "default": {
        'BACKEND': "django_redis.cache.RedisCache",
        'LOCATION': 'redis"//127.0.0.1:6379',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            "PASSWORD": ''
        }
    }
}
复制代码

 

3.限流类的使用

THROTTLE_RATES = {'user': '10/m'}
# s, m, h, d 秒 分 时 天

定义限流类

复制代码
 1 from rest_framework.views import APIView
 2 from rest_framework.response import Response
 3 from rest_framework.authentication import BaseAuthentication
 4 from rest_framework.exceptions import AuthenticationFailed, APIException
 5 from rest_framework.permissions import BasePermission
 6 from rest_framework.throttling import SimpleRateThrottle
 7 from django.core.cache import cache as default_cache
 8 from app01.models import UserInfo
 9 from rest_framework import status
10 
11 class ThrottleException(APIException):
12     status_code = status.HTTP_429_TOO_MANY_REQUESTS
13     default_code = 'throttled'
14 
15 
16 class MyThrottle(SimpleRateThrottle):
17     cache = default_cache  # django中的缓存
18     scope = 'user'  # 用于构造缓存中的key
19     cache_format = 'throttle_%(scope)s_%(ident)s'
20 
21     # 限制配置
22     THROTTLE_RATES = {'user': '10/m'}
23 
24     def get_cache_key(self, request, view):
25         """获取用户的唯一标识"""
26         if request.user:
27             ident = request.user.pk
28         else:
29             ident = self.get_ident(request)  # 获取匿名用户的Ip
30         return self.cache_format % {'scope': self.scope, 'ident': ident}
31 
32     def throttle_failure(self):
33       # 获取下次可以访问的时间间隔
34         wait = self.wait()
35         detail = {
36             'code': 1005,
37             'data': '访问频率限制',
38             'detail': '需要等待{}s'.format(int(wait))
39         }
40         raise ThrottleException(detail)
复制代码

视图类

复制代码
class OrderView(APIView):
    throttle_classes = [MyThrottle, ]

    def get(self, request, *args, **kwargs):
        return Response({
            'code': 0,
            'data': '订单数据'
        })
复制代码

 

 如果我么希望设置5分钟每次,就可以重写如下方法

复制代码
class NewsCreateRateThrottle(SimpleRateThrottle):
    cache = default_cache
    scope = "user"
    cache_format = 'throttle_%(scope)s_%(ident)s'

    THROTTLE_RATES = {'user': "1/5m"}

    def parse_rate(self, rate):
        if rate is None:
            return (None, None)
        num, period = rate.split('/')
        num_requests = int(num)
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[-1]]
        count = int(period[0:-1])
        return (num_requests, duration * count)
复制代码

 

4.多个限流类的使用

我们是可以配置多个限流类的,按照定义顺序逐个执行,执行的结果有以下三种

  • 返回True: 表示限流校验成功,可以继续访问,但会继续执行下一个限流类

  • 返回False: 表示限流校验失败,执行下一个限流类

  • 抛出异常,不会执行下一个限流类了

如果所有的限流类都没有抛出异常,我们又想自定义超出限制的提示信息,就需要在视图类中自定义**`throttled`**方法

复制代码
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import exceptions
from rest_framework import status
from rest_framework.throttling import SimpleRateThrottle
from django.core.cache import cache as default_cache

class ThrottleException(APIException):
    status_code = status.HTTP_429_TOO_MANY_REQUESTS
    default_code = 'throttled'

    
    
class MyThrottle(SimpleRateThrottle):
    cache = default_cache  # django中的缓存
    scope = 'user'  # 用于构造缓存中的key
    cache_format = 'throttle_%(scope)s_%(ident)s'

    # 限制配置
    THROTTLE_RATES = {'user': '10/m'}

    def get_cache_key(self, request, view):
        """获取用户的唯一标识"""
        if request.user:
            ident = request.user.pk
        else:
            ident = self.get_ident(request)  # 获取匿名用户的Ip
        return self.cache_format % {'scope': self.scope, 'ident': ident}

    def throttle_failure(self):
        return False
   
  
class OrderView(APIView):
    throttle_classes = [MyThrottle, ]

    def throttled(self, request, wait):
        detail = {
            'code': 1005,
            'data': '访问频率限制',
            'detail': '需要等待{}s'.format(int(wait))
        }
        raise ThrottleException(detail)

    def get(self, request, *args, **kwargs):
        return Response({
            'code': 0,
            'data': '订单数据'
        })
复制代码

 

5.全局配置

REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES":["xxxx.xxxx.xx.类名","xxxx.xxxx.xx.类名",],
    'DEFAULT_THROTTLE_RATES':{'user':'10/m'}
}

 

6.源码分析

 

标签:ident,self,cache,rest,限流,import,drf
From: https://www.cnblogs.com/MRPython/p/17128577.html

相关文章

  • 6.drf-权限
    认证:判断用户是否登陆,从而获取用户的信息权限:判断当前用户是否有权限访问API接口,例如:普通用户,管理员,超级管理员权限可能是不同的下面通过案例进行介绍模型类fromdj......
  • drf回顾,前端发展历史,vue介绍,第一个helloword,插值语法
    目录drf回顾,前端发展历史,vue介绍,第一个helloword,插值语法今日内容概要今日内容详细1drf回顾2前端发展历史3vue介绍4第一个helloworld5插值语法drf回顾,前端发展历史,vu......
  • 白嫖一个WebAPI限流解决方案
    什么是API限流:API限流是限制用户在一定时间内API请求数量的过程。应用程序编程接口(API)充当用户和软件应用程序之间的网关。例如,当用户单击社交媒体上的发布按钮时,......
  • jwt配置文件 drf-jwt源码执行流程 自定义用户实现jwt的签发和认证 simpleui 权限控制(
    昨日内容回顾#1接口文档的编写-1word,md编写---->存放位置:存放共享文件平台,git上-2第三方的接口文档编写平台-3公司自己开发,使用开源搭建yapi......
  • 详解Redisson分布式限流的实现原理
    摘要:本文将详细介绍下RRateLimiter的具体使用方式、实现原理还有一些注意事项。本文分享自华为云社区《详解Redisson分布式限流的实现原理》,作者:xindoo。我们目前在工作......
  • drf的总结与前端vue框架了解
    drf的总结与前端vue框架了解一、drf知识点整合1、drf入门及规范#1drf入门规范-前后端分离模式-前后端混合-postman-restful规范-drf:django......
  • 1 drf回顾 、2 前端发展历史、 3 vue介绍
    目录1drf回顾2前端发展历史3vue介绍1drf回顾#1drf入门规范 -前后端分离模式-前后端混合-postman-restful规范-drf:django的app#2序列化类......
  • drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式
    drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式目录drf入门之自动生成接口、Drf-Jwt及认证类、定制返回格式接口文档使用coreapi自动生成接口文档步骤jwt介绍和原......
  • drf内容总结
    #1drf入门规范-前后端分离模式-前后端混合-postman-restful规范-drf:django的app#2序列化类(重点)-Serializer-字段类......
  • .Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换
    原文网址:https://www.cnblogs.com/linhuiy/p/12029652.html1.什么是API网关API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API。......