DRF权限和频率
DRF權限 :
權限是什么 :
對某件事情決策的范圍和程度, 就叫權限, 權限在項目開發中是非常重要的.
看下DRF框架給我們提供的權限組件都有哪些方法.
權限組件源碼 :
通過DRF的版本和認證, 也知道全下和頻率都是在niitial方法里初始化的.
其實版本, 認證, 權限, 頻率控制走的源碼流程大致相同, 也是可以在源碼中看到
權限類中一定要有has_permission方法, 否則會拋出異常, 這也是框架給我提供的鉤子,
我們看到在rest_framework.permission這個文件中, 存放了框架給我們提供的所有權限的方法.
其中BasePwemission是寫權限類繼承的一個基礎權限類.
權限的詳細用法舉例 :
我們要搞清楚一點, 我們python代碼是一行一行的執行的, name執行initial方法初始化這些組件的時候, 也是有順序的, 我們的版本在前面, 然后是認證, 然后是權限, 最后是頻率.
在權限執行的時候, 我們認證已經執行結束了
前提在model中的UserInfo表中加了一個字段, 用戶類型的字段, 做好數據遷移.
class MyPermission(BasePermission):message = "VIP用戶才能訪問"def has_permission(self, request, view):"""自定義權限只有vip用戶能訪問,注意我們初始化時候的順序是認證在權限前面的,所以只要認證通過~我們這里就可以通過request.user,拿到我們用戶信息request.auth就能拿到用戶對象"""if request.user and request.auth.type == 2:return Trueelse:return False 第一步, 寫權限類 class TestAuthView(APIView):authentication_classes = [MyAuth, ]permission_classes = [MyPermission, ]def get(self, request, *args, **kwargs):print(request.user)print(request.auth)username = request.userreturn Response(username) 局部視圖函數注冊 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"] } 全局注冊 settings.py?
?
DRF的頻率 :
頻率限制是做什么的 :
開放平臺的API接口調用需要限制其頻率, 以節約服務器資源和避免惡意的頻繁調用.
頻率組件原理 :
DRF中的頻率控制基本原理是基于訪問次數和時間 的, 當然也可以通過自定義的方法來實現.
當請求進來時, 走到我們頻率組件的時候, DRF內部會有一個字典來記錄訪問者的ip,
以這個訪問者的ip為key, value為一個列表, 存放訪問者每次訪問的時間,
{ ip1: [ 第三次訪問時間, 第二次訪問時間, 第一次訪問時間 ] }
把每次訪問最新時間放入列表的最前面, 記錄這樣一個數據結構.
如果設置的是10秒內只能訪問5次,
1, 判斷訪問者的ip是否在這個請求的ip和字典里
2. 保證這個列表里都是最近10秒內的訪問時間
判斷當前請求時間和列表里最早的(也就是最后的)請求時間的差
如果差大于10秒, 說明請求已經不是最近10秒內的, 刪除掉.
繼續判斷單數第二個, 知道差值小于10秒
3. 判斷列表的長度(即訪問次數), 是否大于我們設置的5次
如果大事就限流, 否則放行, 并把時間放入列表的最前面
頻率組件的詳細用法 :
VISIT_RECORD = {} class MyThrottle(object):def __init__(self):self.history = Nonedef allow_request(self, request, view):"""自定義頻率限制60秒內只能訪問三次"""# 獲取用戶IPip = request.META.get("REMOTE_ADDR")timestamp = time.time()if ip not in VISIT_RECORD:VISIT_RECORD[ip] = [timestamp, ]return Truehistory = VISIT_RECORD[ip]self.history = historyhistory.insert(0, timestamp)while history and history[-1] < timestamp - 60:history.pop()if len(history) > 3:return Falseelse:return Truedef wait(self):"""限制時間還剩多少"""timestamp = time.time()return 60 - (timestamp - self.history[-1]) 自定義頻率限制類 REST_FRAMEWORK = {# ......# 頻率限制的配置"DEFAULT_THROTTLE_CLASSES": ["Throttle.throttle.MyThrottle"],} } 配置自定義頻率限制 from rest_framework.throttling import SimpleRateThrottleclass MyVisitThrottle(SimpleRateThrottle):scope = "WD"def get_cache_key(self, request, view):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自帶的頁面進行測試, 沒什么區別
轉載于:https://www.cnblogs.com/dong-/p/9980600.html
總結
- 上一篇: Let Me Count The Way
- 下一篇: JAVA基础——Switch条件语句