酒店

DRF的限流组件(源码分析)-天天滚动

  • 来源:博客园
  • 时间:2023-04-22 07:05:38


(资料图片)

DRF限流组件(源码分析)

限流,限制用户访问频率,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷。

对于匿名用户,使用用户IP作为唯一标识。对于登录用户,使用用户ID或名称作为唯一标识。
缓存={用户标识:[12:33,12:32,12:31,12:30,12,]    1小时/5次   12:34   11:34{
1. 配置缓存
# settings.pyCACHES = {    "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: ifengfrom django.core.cache import cache as default_cachefrom rest_framework import exceptionsfrom rest_framework import statusfrom rest_framework.throttling import SimpleRateThrottleclass 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()方法

关键词:

推荐内容

Copyright @  2015-2032 华西旅行网版权所有  

备案号:京ICP备2022016840号-35

  

联系邮箱: 920 891 263@qq.com