python - Django 休息框架 - 我如何限制对 API 端点的请求?
问题描述
我使用 Django Rest Framework 创建了一个 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',
)
}
在我的views.py
:
class UserSecThrottle(UserRateThrottle):
scope = 'user_sec'
class UserMinThrottle(UserRateThrottle):
scope = 'user_min'
class UserHourThrottle(UserRateThrottle):
scope = 'user_hour'
因此,如果某个用户在一分钟内执行超过 120 个查询,则该用户将被阻止一分钟,如果超出小时限制,则该用户将被阻止一小时。有什么方法可以决定一个用户被屏蔽了多少?例如,如果某人在一分钟内执行超过 120 个查询,我想阻止他们 10 分钟。任何建议表示赞赏。
解决方案
要创建自定义节流阀,请覆盖BaseThrottle
并实施.allow_request(self, request, view)
. True
如果请求应该被允许,则该方法应该返回,False
否则。
或者,您也可以覆盖该.wait()
方法。如果实施,.wait()
应返回建议的等待秒数,然后再尝试下一个请求,或者无。仅当先前已返回.wait()
时才会调用该方法。.allow_request()
False
如果.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
推荐阅读
- c++ - 纯抽象基类的虚拟析构函数
- ubuntu-16.04 - 如何在 Ckan 上初始化 db ini?
- javascript - 如何在 pug 中定义 vue 模板?
- c# - 如何使用 IHttpActionResult 接口从 WebApi 2 操作返回 html 文档?
- c# - c# how do i detect when a user clicks anywhere inside a form
- c# - will it auto compile when a razor page file is updated on server?
- python - Running qsub with anaconda environment
- google-tag-manager - http GET, finding tag name for fired GTM event
- uipath - UiPath: Collection.contains("string") doesn't appear to be returning Boolean as expected
- javascript - ngFor 不会在 NavigationEnd 事件 Angular 6+ 上加载动态填充的数组