英文:
Django Rest Framework Rate Limit Dynamic based on User Type
问题
I'm building an API using Django Rest Framework (DRF) and I'm facing an issue with rate limiting. Specifically, I need to set different rate limits for different types of users:
Staff members: 1000 requests per day
Normal users: 100 requests per day
Anonymous users: 10 requests per day
I've tried several approaches but haven't been successful so far. Can anyone provide guidance on how to achieve dynamic rate limiting based on user type using DRF?
I've been trying to set up dynamic rate limiting in Django Rest Framework (DRF) based on user type. Specifically, I've created four throttling classes using the built-in DRF throttling classes: PublicThrottle, PrivateAnonThrottle, PrivateFreeUserThrottle, and PrivatePaidUserThrottle. I've defined the throttle rate for the PublicThrottle class as 1000/day, and set the scope attribute for each of the other classes to a unique value.
For the PrivatePaidUserThrottle class, I've overridden the allow_request method to check if the user making the request is a staff member. If so, I want to use the private_paid_user scope, otherwise I want to use the private_free_user scope.
What I expected:
I expected that the rate limits would be enforced based on the user type. Specifically, I expected that staff members would have a rate limit of 1000/day, normal users would have a rate limit of 100/day, and anonymous users would have a rate limit of 10/day. However, the rate limiting doesn't seem to be working as expected, and I've been unable to find helpful documentation on this topic.
from rest_framework.throttling import ScopedRateThrottle, UserRateThrottle, AnonRateThrottle
from rest_framework import throttling
class PublicThrottle(ScopedRateThrottle):
THROTTLE_RATES = {
'public': '1000/day' # Define the throttle rate for public APIs
}
class PrivateAnonThrottle(AnonRateThrottle):
scope = "private_anon"
class PrivateFreeUserThrottle(UserRateThrottle):
scope = "private_free_user"
class PrivatPaidUserThrottle(UserRateThrottle):
scope = "private_paid_user"
def allow_request(self, request, view):
if request.user.is_staff:
self.scope = "private_paid_user"
else:
self.scope = "private_free_user"
return super().allow_request(request, view)
settings.py
for easier testing I decreased the rates
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# token authentication is used for the API
'rest_framework.authentication.TokenAuthentication',
# session authentication is used for the admin
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
],
# for rate limiting
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/day',
"user": "50/day",
"private_anon": "3/day",
"private_free_user": "7/day",
"private_paid_user": "10/day",
},
}
After 5 requests, even if it's a staff account, it still gives:
{'detail': 'Request was throttled. Expected available in 86398 seconds.'}
Can anyone suggest what I might be doing wrong, or provide guidance on how to achieve dynamic rate limiting based on user type using DRF?
英文:
I'm building an API using Django Rest Framework (DRF) and I'm facing an issue with rate limiting. Specifically, I need to set different rate limits for different types of users:
Staff members: 1000 requests per day
Normal users: 100 requests per day
Anonymous users: 10 requests per day
I've tried several approaches but haven't been successful so far. Can anyone provide guidance on how to achieve dynamic rate limiting based on user type using DRF?
I've been trying to set up dynamic rate limiting in Django Rest Framework (DRF) based on user type. Specifically, I've created four throttling classes using the built-in DRF throttling classes: PublicThrottle, PrivateAnonThrottle, PrivateFreeUserThrottle, and PrivatePaidUserThrottle. I've defined the throttle rate for the PublicThrottle class as 1000/day, and set the scope attribute for each of the other classes to a unique value.
For the PrivatePaidUserThrottle class, I've overridden the allow_request method to check if the user making the request is a staff member. If so, I want to use the private_paid_user scope, otherwise I want to use the private_free_user scope.
What I expected:
I expected that the rate limits would be enforced based on the user type. Specifically, I expected that staff members would have a rate limit of 1000/day, normal users would have a rate limit of 100/day, and anonymous users would have a rate limit of 10/day. However, the rate limiting doesn't seem to be working as expected, and I've been unable to find helpful documentation on this topic.
from rest_framework.throttling import ScopedRateThrottle, UserRateThrottle, AnonRateThrottle
from rest_framework import throttling
class PublicThrottle(ScopedRateThrottle):
THROTTLE_RATES = {
'public': '1000/day' # Define the throttle rate for public APIs
}
class PrivateAnonThrottle(AnonRateThrottle):
scope = "private_anon"
class PrivateFreeUserThrottle(UserRateThrottle):
scope = "private_free_user"
class PrivatPaidUserThrottle(UserRateThrottle):
scope = "private_paid_user"
def allow_request(self, request, view):
if request.user.is_staff:
self.scope = "private_paid_user"
else:
self.scope = "private_free_user"
return super().allow_request(request, view)
settings.py
for easier testing I decreased the rates
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# token authentication is used for the API
'rest_framework.authentication.TokenAuthentication',
# session authentication is used for the admin
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
],
# for rate limiting
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/day',
"user": "50/day",
"private_anon": "3/day",
"private_free_user": "7/day",
"private_paid_user": "10/day",
},
}
after 5 requests, even if its a staff account, it still gives
{'detail': 'Request was throttled. Expected available in 86398 seconds.'}
Can anyone suggest what I might be doing wrong, or provide guidance on how to achieve dynamic rate limiting based on user type using DRF?
答案1
得分: 1
请将 DEFAULT_THROTTLE_CLASSES 更改为您自定义的类,而不是使用内置类。
'DEFAULT_THROTTLE_CLASSES': [
'example.throttles.PublicThrottle',
'example.throttles.PrivateAnonThrottle',
'example.throttles.PrivateFreeUserThrottle',
'example.throttles.PrivatPaidUserThrottle'
]
注意:请将 "example.throttles" 更改为您的模块路径。
文档链接 - https://www.django-rest-framework.org/api-guide/throttling/#userratethrottle
英文:
You should give DEFAULT_THROTTLE_CLASSES as your own custom classes instead of built-in ones.
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
]
should be changed to
'DEFAULT_THROTTLE_CLASSES': [
'example.throttles.PublicThrottle',
'example.throttles.PrivateAnonThrottle',
'example.throttles.PrivateFreeUserThrottle',
'example.throttles.PrivatPaidUserThrottle'
]
Note: Please change example.throttles to your module path.
Documentation - https://www.django-rest-framework.org/api-guide/throttling/#userratethrottle
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论