rest_framework throttling 限流
rest_framework throttling 限流
1. 限流
限流设置也是List。
在执行view前,限流列表中的每个限流器都会执行,任意一次检查未通过,抛出fexceptions.Throttled exception,后续操作终止。
1.1. 配置
# 全局配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
}
自定义限流类配置
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
class ExampleView(APIView):
throttle_classes = [UserRateThrottle]
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
Or, if you're using the @api_view decorator with function based views.
@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
1.2. 客户端识别 How clients are identified
客户端识别基于 X-Forwarded-For HTTP header and REMOTE_ADDR WSGI
优先使用前者,如果前者不存在,使用后者。
NUM_PROXIES用于指定使用哪一个ip,非0使用X-Forwarded-For最后一项,否则使用REMOTE_ADDR
1.3. 内置限流类
AnonRateThrottle
限制未认证的用户。识别是基于请求的IP。
UserRateThrottle
基于用户限制全局请求频率。用户标识用于生成一个唯一的密钥来加以限制。未登录用户基于ip进行限制。
ScopedRateThrottle
用于限制对API特定部分的访问。只有当正在访问的视图包含 .throttle_scope 属性时才会应用此限制。
2. 案例
自定义限流类实现30秒内限制访问3次
# throttle.py
from rest_framework.throttling import BaseThrottle
import time
VISIT_RECORD = {}
# 限流类
class VisitThrottle(BaseThrottle):
def __init__(self):
super().__init__()
self.history = None
def allow_request(self, request, view):
remote_addr = request.META.get("REMOTE_ADDR")
ctime = time.time()
history = VISIT_RECORD.get(remote_addr)
if history is None:
VISIT_RECORD[remote_addr] = [ctime,]
return True
self.history = history
while history and history[-1] < ctime -30:
history.pop()
if len(history) < 3:
history.insert(0, ctime)
return True
return False
def wait(self):
ctime = time.time()
return 30 - (ctime - self.history[-1])
# APIview
from .throtlle import VisitThrottle
class TestModelObjectView(generics.RetrieveAPIView):
queryset = TestModels.objects.all()
serializer_class = TestModelsSerializer
permission_classes = [permissions.AllowAny]
throttle_classes = [VisitThrottle,]
日拱一卒无有尽,功不唐捐终入海

浙公网安备 33010602011771号