1. 程式人生 > >DRF之限制單位時間訪問次數

DRF之限制單位時間訪問次數

參數 sse auth resp ews quest anon http period

1、節流源碼流程:

# step 1
def dispatch(self, request, *args, **kwargs):
    try:
        self.initial(request, *args, **kwargs)


# step 2
def initial(self, request, *args, **kwargs):
    self.perform_authentication(request)  # 先認證
    self.check_permissions(request)  # 隨後權限管理
    self.check_throttles(request)  # 最後是節流管理
    

# step 3
def check_throttles(self, request):
    for throttle in self.get_throttles():
        # 調用類的allow_request函數,返回False,則節流有效,反之,不節流
        if not throttle.allow_request(request, self):
            self.throttled(request, throttle.wait())


# step 4 :獲取節流類的實例化對象列表
def get_throttles(self):
    return [throttle() for throttle in self.throttle_classes]


# step 5

from rest_framework.throttling import BaseThrottle

# 默認的節流類
class SimpleRateThrottle(BaseThrottle):
    cache = default_cache
    timer = time.time
    cache_format = 'throttle_%(scope)s_%(ident)s'
    scope = None
    THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES  # 可以自定義

    def get_cache_key(self, request, view):
        pass

2、自定義節流:

# 相關參數的解析方式
def parse_rate(self, rate):
    if rate is None:
        return (None, None)
        
    num, period = rate.split('/')
    num_requests = int(num)
    duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]
    return (num_requests, duration)


# setting.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES':{
        'anon':'5/m'  # 表示每分鐘只能訪問5次數
    },
}


# views.py
class MyThrottle(SimpleRateThrottle):
    scope = 'anon'  # 標識符

    def get_cache_key(self, request, view):
        return self.cache_format % {
            'scope': self.scope,
            'ident': self.get_ident(request)
        }


class Throttle(object):
    throttle_classes = [MyThrottle,]


class UserView(Auth,Throttle,APIView):
    """所有用戶都有權限,也可以限制匿名用戶,去掉Auth類參數即可"""
    def get(self,request,*args,**kwargs):
        return HttpResponse('<h1>用戶界面</h1>')

3、錯誤頁面:

技術分享圖片

4、請求次數限制方法,可以對ip(對代理用戶無效)、用戶名或者手機等特定標識節流:

dict={
    ip:[11:12,11:10,11:01,]  # 最新訪問時間從左側插入
    # 例如若限制為:5/m,那麽每次插入元素前都會與相應的元素比較時間差,若在時間差內則插入,否則不插入
}

DRF之限制單位時間訪問次數