DRF的權限和頻率

DRF的權限

權限組件源碼

權限和頻率以及版本認證都是在initial方法裏初始化的python

咱們的權限類必定要有has_permission方法~不然就會拋出異常~~這也是框架給我提供的鉤子~~服務器

 在rest_framework.permissions這個文件中~存放了框架給咱們提供的全部權限的方法~~數據結構

主要說下BasePermission 這個是咱們寫權限類繼承的一個基礎權限類~~~ 框架

權限的詳細用法

initial方法在初始化的時候是有順序的:版本-->權限-->頻率 ide

寫權限類post

class MyPermission(object):
    message = '權限不足'

    def has_permission(self, request, view):
        # 權限邏輯
        """
        自定義VIP用戶權限,
        注意咱們初始化時候的順序是:版本-->權限-->頻率 
        因此只要認證經過咱們這裏就能夠經過request.user,拿到咱們用戶信息
        request.auth就能拿到用戶對象
        """
        user_obj = request.user
        if user_obj.type == 1:
            return False
        else:
            return True

 局部視圖註冊測試

class TestPermission(APIView):
    authentication_classes = [MyAuth, ]
    permission_classes = [MyPermission, ]

    def get(self, request):
        return Response('vip用戶能看的電影')

全局註冊 settings.pyspa

REST_FRAMEWORK = {
    # 默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    # 容許的版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # 版本使用的參數名稱
    'VERSION_PARAM': 'version',
    # 默認使用的版本
    'DEFAULT_VERSION': 'v1',
    # 配置全局認證
    # 'DEFAULT_AUTHENTICATION_CLASSES': ["BRQP.utils.MyAuth", ]
    # 配置全局權限
    "DEFAULT_PERMISSION_CLASSES": ["BROP.utils.MyPermission"]
}

 DRF的頻率

頻率限制是作什麼的

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

咱們的DRF提供了一些頻率限制的方法。rest

頻率組件源碼

版本、認證、權限、頻率這幾個組件的源碼是一個流程。

頻率組件原理

DRF中的頻率控制基本原理是基於訪問次數和時間的,固然咱們能夠經過本身定義的方法來實現。

當咱們請求進來,走到咱們頻率組件的時候,DRF內部會有一個字典來記錄訪問者的IP,

以這個訪問者的IP爲key,value爲一個列表,存放訪問者每次訪問的時間,

{  IP1: [第三次訪問時間,第二次訪問時間,第一次訪問時間],}

把每次訪問最新時間放入列表的最前面,記錄這樣一個數據結構後,經過什麼方式限流呢~~

若是咱們設置的是10秒內只能訪問5次,

  -- 1,判斷訪問者的IP是否在這個請求IP的字典裏

  -- 2,保證這個列表裏都是最近10秒內的訪問的時間

      判斷當前請求時間和列表裏最先的(也就是最後的一個的)請求時間的差

      若是差大於10秒,說明請求已經不是最近10秒內的,刪除掉,

      繼續判斷倒數第二個,直到差值小於10秒

  -- 3,判斷列表的長度(即訪問次數),是否大於咱們設置的5次,

      若是大於就限流,不然放行,並把時間放入列表的最前面。

頻率組件的詳細用法

頻率組件的配置方式其實跟上面的組件都同樣。

自定義的頻率限制類

import time

VISIT_RECORD = {}


class MyThrottle(object):
    """
    一分鐘容許訪問5次
    """

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

    def allow_request(self, request, view):
        # 獲取用戶的IP地址META   REMOTE_ADDR
        ip = request.META.get('REMOTE_ADDR', '')
        # 若是ip不在字典中
        if ip not in VISIT_RECORD:
            # 則ip做爲key,當前時間做爲value加入到VISIT_RECORD中
            VISIT_RECORD[ip] = [time.time(), ]
        # 若是ip在字典中
        else:
            history = VISIT_RECORD[ip]
            # 用self.history接一下變量
            self.history = history
            # 把最近訪問的時間插入到列表的最前面
            history.insert(0, time.time())
            # 先確保列表時間是容許範圍以內的
            while self.history[0] - self.history[-1] > 60:
                self.history.pop()
                # 判斷列表長度
            if not len(self.history) <= 5:
                return False
        return True

    # 等待信息
    def wait(self):
        # 超出訪問頻率後提示限制時間還剩多少
        return 60 - (self.history[0] - self.history[-1])

配置自定義頻率限制

REST_FRAMEWORK = {
    # ......
    # 頻率限制的配置
    "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyThrottle"],
    }
}

使用自帶的頻率限制類

from rest_framework.throttling import SimpleRateThrottle


class DRFThrottle(SimpleRateThrottle):
    scope = 'WD'

    def get_cache_key(self, request, view):
        # 拿ip地址
        return self.get_ident(request)

配置頻率限制

REST_FRAMEWORK = {
    # 頻率限制的配置
    # "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyVisitThrottle"],
    "DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyThrottle"],
    "DEFAULT_THROTTLE_RATES":{
        'WD':'5/m',         #速率配置每分鐘不能超過5次訪問,WD是scope定義的值,

    }
}

咱們能夠在postman~~或者DRF自帶的頁面進行測試都~~能夠沒什麼區別~~  

相關文章
相關標籤/搜索