Django Rest Framework 根据用户类型动态限制速率。

huangapple go评论59阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月16日 05:29:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75465615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定