Django rest框架如何将请求限制到API端点?

2024-06-16 11:11:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Django Rest框架创建了一个API,现在我正在开发一个速率限制系统,以避免垃圾邮件。内置节流系统运行良好,我成功添加了多个节流:

REST_FRAMEWORK = {
        # 'DEFAULT_AUTHENTICATION_CLASSES': (
        #     "xapi.authentication_backends.TokenBackend",
        # ),
        'DEFAULT_THROTTLE_CLASSES': [
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ],
        'DEFAULT_THROTTLE_RATES': {
            'anon': '70/minute',
            'user': '70/minute',
            'user_sec': '2/second',
            'user_min': '120/minute',
            'user_hour': '7200/hour',
        },
        
        'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        )
    }

在我的{}中:

class UserSecThrottle(UserRateThrottle):
    scope = 'user_sec'

class UserMinThrottle(UserRateThrottle):
    scope = 'user_min'

class UserHourThrottle(UserRateThrottle):
    scope = 'user_hour'

因此,如果某个用户在一分钟内执行120次以上的查询,该用户将被阻止一分钟,如果超过小时限制,该用户将被阻止一小时。是否有某种方法来决定用户被阻止的程度?例如,如果某人在一分钟内执行120次以上的查询,我想阻止他10分钟。任何建议都将不胜感激


Tags: 用户restdefault系统frameworkclassclassesscope
1条回答
网友
1楼 · 发布于 2024-06-16 11:11:20

要创建自定义节流阀,请重写BaseThrottle并实现.allow_request(self, request, view)。如果请求应该被允许,那么方法应该返回True,否则返回False

还可以选择重写.wait()方法。如果实现,.wait()应该返回建议的等待秒数,然后再尝试下一个请求,或者不返回。只有当.allow_request()以前返回了False时,才会调用.wait()方法

如果实现了.wait()方法并限制了请求,那么响应中将包含一个Retry After头

import random
class CustomThrottle(throttling.BaseThrottle):
    def allow_request(self, request, view):
         """
         Return `True` if the request should be allowed, `False` otherwise.
         """
         return random.randint(1, 10) != 1

    def wait(self):
        """
        Optionally, return a recommended number of seconds to wait before
        the next request.
        """
        cu_second = 600
        return cu_second

class UserSecThrottle(CustomThrottle,UserRateThrottle):   # or AnonRateThrottle
    scope = 'user_sec'

class ExampleView(APIView):
    throttle_classes = [UserSecThrottle]
    .......

参考:https://www.django-rest-framework.org/api-guide/throttling/#custom-throttles

相关问题 更多 >