【问题标题】:How to set multiple rate limits , per 10sec, per 10min, per 1 day using django-ratelimit or throttling?如何使用 django-ratelimit 或节流设置多个速率限制,每 10 秒,每 10 分钟,每 1 天?
【发布时间】:2019-11-14 12:52:35
【问题描述】:

我想根据 10 秒、10 分钟和 1 天的持续时间为我的视图设置速率限制。因此,假设用户每天可以发送 20 个请求/10 秒、100 个请求/10 分钟和 1000 个请求。

我尝试过限制,但找不到任何设置多个请求的方法。 我已经尝试过 django-ratelimit 包,但我也找不到任何这样的选项,因为它为速率设置了一个字符串,例如 rate = '5/10m'。 请问有什么办法可以解决这个问题

【问题讨论】:

    标签: django django-rest-framework throttling rate-limiting


    【解决方案1】:

    documentation on django-ratelimit 对此进行了介绍。您可以在同一个视图上定义多个 @ratelimit 装饰器。

    此外,费率格式允许您添加number to the denominator

    您还可以指定单位数,即:X/Yu 其中Y 是单位数。如果省略u,则假定为秒。因此,以下是等价的,都表示“每五分钟一百个请求”:

    100/5m
    100/300s
    100/300
    

    因此,您可以将这些限制定义为:

    from ratelimit.decorators import ratelimit
    
    @ratelimit(key='user', rate='20/10s')
    @ratelimit(key='user', rate='100/10m')
    @ratelimit(key='user', rate='1000/d')
    def some_view(request):
        pass

    对于基于类的视图(例如ViewSet),您可以使用@method_decorator 来装饰它,例如:

    django.utils.decorators import method_decorator
    from ratelimit.decorators import ratelimit
    
    @method_decorator(ratelimit(key='user', rate='20/10s'), name='dispatch')
    @method_decorator(ratelimit(key='user', rate='100/10m'), name='dispatch')
    @method_decorator(ratelimit(key='user', rate='1000/d'), name='dispatch')
    class MyViewSet(ViewSet):
        # ...

    【讨论】:

    • 我们如何为视图集设置此速率限制?以下是我的视图集,我想为此实施速率限制。 class AssetParentTableViewset(viewsets.ModelViewSet): queryset = AssetParentTable.objects.all() serializer_class= AssetParentTableSerializer filterset_class= AssetParentTableFilter
    • @saadatali:您可以在dispatch 方法上应用method_decorators。
    【解决方案2】:

    因为我在下面使用,不适用于通用视图。

    @method_decorator(ratelimit(key='user', rate='1000/d'), name='dispatch')
    class MyViewSet(ViewSet):
    

    我找到了其他解决方案。

    from django.http import JsonResponse
    from ratelimit.decorators import ratelimit
    
    class RateLimitForSecurity(View):
        @ratelimit(key='ip', rate='30/m')
        def dispatch(self, request, *args, **kwargs):
            was_limited = getattr(request, 'limited', False)
            if was_limited:
                return JsonResponse({"code": 1, 'msg': 'try many times'},json_dumps_params={'ensure_ascii':False})
    
            return super().dispatch(request, *args, **kwargs)
    
    class IndexView(RateLimitForSecurity, generic.ListView):
          # same as before
    

    【讨论】:

      【解决方案3】:

      我正在研究这个,发现您可以覆盖油门类函数 parse_rate 并且可以根据您的需要进行自定义

      from rest_framework.throttling import UserRateThrottle
      class ThirdPartyMonthlyThrottle(UserRateThrottle):
          scope = 'third_party_monthly'
      
          def parse_rate(self, rate):
              if rate is None:
                  return None, None
              num, period = rate.split('/')
              num_requests = int(num)
              duration = int(period)*86400
              return num_requests, duration
      
      
      'DEFAULT_THROTTLE_RATES': {
              'third_party_monthly': '3/30'
          }
      

      这可以解释为每月 3 个请求

      【讨论】:

        【解决方案4】:

        你可以这样做

        from ratelimit.decorators import ratelimit
        from http import HTTPStatus
        
        @ratelimit(key='user_or_ip', rate='1/10m', method=['POST'])
        def ajax_add_review(request, username):
            was_limited = getattr(request, 'limited', False)
                if was_limited:
                    return JsonResponse({"error": 'limit crossed'}, status=HTTPStatus.BAD_REQUEST)
        

        【讨论】:

          猜你喜欢
          • 2016-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-30
          • 2018-11-11
          • 2023-03-16
          相关资源
          最近更新 更多