【DRF頻率】

開發平臺的API接口調用須要限制其頻率,以節約服務器資源和避免惡意的頻繁調用.服務器

DRF就爲咱們提供了一些頻率限制的方法.
DRF中的版本、認證、權限、頻率組件的源碼是一個流程,且頻率組件在最後執行.數據結構

@ide

 


DRF頻率組件原理
·
DRF中的頻率控制基本原理是基於訪問次數和時間的,固然咱們也能夠經過本身定義的方法來實現.
當請求進來,走到咱們的頻率組件時,DRF內部會有一個字典來記錄訪問者的IP.
以這個字典的IP爲key,value爲一個列表,存放訪問者每次訪問的時間:{PI1: [第三次訪問時間, 第二次訪問時間, 第一次訪問時間, ]}
把每次訪問的最新時間放入列表的最前面,記錄這樣一個數據結構後,經過以下方式限制:
·
若是咱們設置的是10秒內只能訪問5次:測試

  1. 判斷訪問者的IP是否在這個請求IP的字典裏.
  2. 保證這個列表裏都是都是最近10秒內訪問的時間.
    : 判斷當前請求時間和列表裏最先的(也就是最後一個)請求時間差
    : 若是差大於10秒,說明請求不是最近10秒內的,刪除掉最後一個
    : 繼續判斷倒數第二個、第三個,直到差小於10秒爲止
  3. 判斷列表的長度(即訪問次數)是否大於咱們設置的5次.
    : 若是大於,則限制其訪問
    : 若是小於,則放行,並把時間記錄到列表的最前面

使用自帶的頻率限制類

首先 配置頻率限制類spa

from rest_framework.throttling import SimpleRateThrottle  #  導入內置的頻率限制類

class DRFThrottle(SimpleRateThrottle):
    """注意:這裏都是必備的屬性、方法和返回值"""
    scope = 'WD'
    def get_cache_key(self, request, view):
        # 拿IP地址
        return self.get_ident(request)

而後 配置文件3d

REST_FRAMEWORK = {
    # 指定頻率限制的類
    "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.DRFThrottle'],
    # WD是scope定義的值,3/m表示每分鐘不能超過3次訪問
    "DEFAULT_THROTTLE_RATES": {"WD": "3/m"},
}

"""
若是隻是想給單個視圖作頻率限制:
則刪除這裏的"DEFAULT_THROTTLE_CLASSES"配置項
並在要作頻率限制的視圖中指定頻率限制類便可
指定語法:throttle_classes = ["頻率限制類", ]
"""

開始測試rest

訪問測試頁面,連續刷新3次後,可看到:
在這裏插入圖片描述blog


使用自定義的頻率限制類

首先 自定義頻率限制類接口

import time

VISIT_RECORD = {}  # 限制訪問次數的字典

class MyThrottle():
    """
    自定義頻率限制類,一分鐘容許訪問5次
    注意:自定義頻率限制類中必需要有allow_request和wait方法
    前者用於頻率限制的邏輯,後者用於返回限制時間還剩多少秒
    """

    def __init__(self):
        self.history = []

    def allow_request(self, request, view):
        """用於限制訪問的邏輯"""
        # 獲取用戶的IP地址
        ip = request.META.get('REMOTE_ADDR')
        if ip not in VISIT_RECORD:
            VISIT_RECORD[ip] = [time.time(), ]
        else:
            history = VISIT_RECORD[ip]
            self.history = history
            history.insert(0, time.time())
            # 確保訪問時間在容許範圍以內
            while self.history[0] - self.history[-1] > 60:
                self.history.pop()
            # 肯定訪問次數在容許的範圍內
            if len(self.history) >= 5:
                return False
        return True

    def wait(self):
        """用於返回限制時間還剩多少秒"""
        return 60 - (self.history[0] - self.history[-1])

而後 配置文件圖片

REST_FRAMEWORK = {
    # 指定自定義的頻率限制類
    "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.MyThrottle'],
}

> """
若是隻是想給單個視圖作頻率限制:
則刪除這裏的"DEFAULT_THROTTLE_CLASSES"配置項
並在要作頻率限制的視圖中指定頻率限制類便可
指定語法:throttle_classes = ["頻率限制類", ]
"""

好了,就到這裏吧.

相關文章
相關標籤/搜索