如何用Django Rest框架节流API
你是否曾在经过一座天桥时注意到桥上的重量限制标志?这些限制是为了确保公共安全而设置的。Django REST框架使用了一个类似的过程,名为节流,控制客户端对API的请求速率。这种速率限制可以确保可扩展性,防止性能缓慢和拒绝服务(DoS)攻击,并改善整体用户体验。
Django REST框架在rest_framework.throttling模块中有三个节流类 – AnonRate、UserRate和ScopedRate节流。所有这些类都指定了节流规则,标志着范围内给定时间内的最大请求数。这些类有不同的机制来指定范围–将以前的信息与新的请求进行比较。让我们深入挖掘一下DRF的节流功能。
- AnonRateThrottle
- UserRateThrottle
- ScopedRateThrottle
AnonRateThrottle
AnonRateThrottle将对未认证的用户进行节流。使用传入请求的IP地址,生成一个唯一的密钥来进行节流。允许的请求率是由以下任何一项决定的。
- 类上的速率属性–通过重写AnonRateThrottle并设置该属性来提供。
- DEFAULT_THROTTLE_RATES[‘anon’] 设置。
让我们在全局范围内设置节流策略。你可以打开settings.py文件,提到节流类和节流率,如下所示。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'🙁
'rest_framework.authentication.BasicAuthentication',
)
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day'
}
}
你可以把秒、分、小时或日作为节流周期(THROTTLE RATES)。
让我们尝试用HTTPie命令来检索机器人的信息。在这里,我们在不提供任何凭证的情况下检索列表。
http GET :8000/robot/
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Language: en
Content-Length: 2106
Content-Type: application/json
Date: Sat, 02 Oct 2021 14:29:40 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Accept-Language
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
[
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-05-10T00:00:00Z",
"name": "IRB 1100",
"owner": "sonu",
"price": 25000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/7/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-08-10T00:00:00Z",
"name": "IRB 120",
"owner": "sonu",
"price": 35000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/8/"
},
]
这里,匿名节流率被设定为每天2个API请求。所以,它不允许超过两个请求。如果你的请求率超过2个请求,你将得到以下输出。
UserRateThrottle
UserRateThrottle控制认证用户和非认证用户发送请求的速率。用户ID是认证请求的唯一缓存密钥,而IP地址是未认证请求的唯一缓存密钥。
允许的请求率是由以下任何一项决定的。
- 类上的速率属性–通过重写UserRateThrottle并设置该属性来提供。
- DEFAULT_THROTTLE_RATES[‘user’] 设置。
你可以按以下方式编辑REST_FRAMEWORK字典。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'🙁
'rest_framework.authentication.BasicAuthentication',
)
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day',
'user': '5/day'
}
}
我们的REST_FRAMEWORK字典中的节流规则如下。
- 未经认证的用户每天最多只能提出2次请求
- 已认证的用户每天最多有5个请求
下面这个经过认证的HTTPie命令允许每天有5个请求。
http -a “sonu”:”sn@pswrd” GET :8000/robot/
restful网络服务提出了太多的请求,每天超过5个请求。
ScopedRateThrottle
ScopedRateThrottle类控制我们RESTFul网络服务中特定功能的请求率。这里被访问的视图应该包括.throttle_scope属性。让我们为我们的RobotDetail类添加一个节流范围,并提及该范围的节流率。
首先,让我们导入ScopedRateThrottle。
from rest_framework.throttling import ScopedRateThrottle
现在添加以下几行代码
throttle_scope = 'robots'
throttle_classes = (ScopedRateThrottle,)
我们的RobotDetail类看起来如下。
class RobotDetail(generics.RetrieveUpdateDestroyAPIView):
throttle_scope = 'robots'
throttle_classes = (ScopedRateThrottle,)
permission_classes = (
permissions.IsAuthenticatedOrReadOnly,
custompermission.IsCurrentUserOwnerOrReadOnly,
)
queryset = Robot.objects.all()
serializer_class = RobotSerializer
name = 'robot-detail'
接下来,让我们为范围 “机器人 “添加节流率。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'🙁
'rest_framework.authentication.BasicAuthentication',
)
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day',
'user': '5/day',
'robots': '3/day'
}
}
让我们试试通过认证的HTTPie请求来获取基于id的机器人,它利用RobotDetail类来获取基于id的机器人。命令如下。
http -a “sonu”:”sn@pswrd” GET :8000/robot/2/
输出
在这里,我们的范围率是每天3个请求。如果超过3个请求,我们将得到太多的请求。第4个请求的输出情况如下。