如何使用 Django Rest Framework 限制 API
您是否曾经穿过天桥并注意到表明桥梁重量限制的标志?实施这些限制是为了确保公共安全。 Django REST Framework 使用一个名为 throttling 的类似过程来控制客户端可以向 API 发出的请求速率。这种速率限制限制可以确保可扩展性,防止性能下降和拒绝服务 (DoS) 攻击,并改善整体用户体验。
Django REST 框架在rest_framework.throttling模块中有三个节流类——AnonRate、UserRate 和 ScopedRate 节流器。所有这些类都指定了表示范围内给定时间内最大请求数的限制规则。这些类有不同的机制来指定范围——将以前的信息与新请求进行比较。让我们深入研究 DRF 节流功能。
- AnonRateThrottle
- 用户速率限制
- ScopedRateThrottle
注意:请参阅在 API 中添加权限 – Django REST Framework 和自定义对象级别权限 – Django REST Framework 以利用权限与限制
AnonRateThrottle
AnonRateThrottle 将限制未经身份验证的用户。使用传入请求的 IP 地址,生成一个唯一的密钥来限制。允许的请求率由以下任何一项确定:
- 类的 rate 属性 - 通过覆盖 AnonRateThrottle 并设置该属性提供。
- DEFAULT_THROTTLE_RATES['anon'] 设置。
让我们全局设置限制策略。您可以打开 settings.py 文件并提及油门类别和油门速率,如下所示:
Python3
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'🙁
'rest_framework.authentication.BasicAuthentication',
)
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/day'
}
}
Python3
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'
}
}
Python3
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'
Python3
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'
}
}
您可以包括秒、分钟、小时或天作为节流周期 (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 控制经过身份验证和未经身份验证的用户发送请求的速率。用户 id 是已验证请求的唯一缓存键,IP 地址是未验证请求的唯一缓存键。
允许的请求率由以下任何一项确定:
- 类上的 rate 属性 - 通过覆盖 UserRateThrottle 并设置该属性提供。
- DEFAULT_THROTTLE_RATES['user'] 设置。
您可以按如下方式编辑 REST_FRAMEWORK 字典:
蟒蛇3
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 Web 服务引发的请求过多,每天超过 5 个请求。
ScopedRateThrottle
ScopedRateThrottle 类控制对 RESTFul Web 服务中特定功能的请求速率。这里正在访问的视图应该包含 .throttle_scope 属性。让我们向 RobotDetail 类添加一个油门作用域并提及作用域的节流率。
首先,让我们导入 ScopedRateThrottle。
from rest_framework.throttling import ScopedRateThrottle
现在添加以下代码行
throttle_scope = 'robots'
throttle_classes = (ScopedRateThrottle,)
我们的 RobotDetail 类如下所示:
蟒蛇3
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'
接下来,让我们为范围“机器人”添加节流率。
蟒蛇3
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 个请求的输出如下: