權限控制
前言
用戶驗證用戶權限,根據不同訪問權限控制對不同內容的訪問,
建議了解視圖、token驗證的內容,
使用流程
- 自定義訪問權限類,繼承
BasePermission,重寫has_permission()方法,如果權限通過,就回傳True,不通過就回傳False,has_permission()方法接受兩個引數,分別是request和view,也就是視圖類的實體化本身,

- 配置,
區域配置:
permission_classes = [MyUserPermission]
全域配置:
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES': ['libs.MyAuth.UserPermission',],
}
示例
class SVIPPermission(BasePermission): # 推薦繼承BasePermission類
# message = 'You do not have permission to perform this action.'#默認值
message = '無此權限!!!'
def has_permission(self, request, view):
if request.user.user_type == 3:
return False # False為沒權限
# view.queryset = # 可以使用這種方式控制視圖中要處理的資料(根據不同權限)
return True # True為有權限
原始碼分析
進入dispatch函式,查看initial方法(執行三大驗證)中的check_permissions方法:

self.check_permissions(request)將會根據request中的用戶內容進行權限控制,



由上可知,permission_classes要么讀取組態檔中的DEFAULT_PERMISSION_CLASSES(全域),要么就在視圖類中直接對permission_classes賦值(區域),
節流限制
前言
控制網站訪問頻率,
使用流程
- 自定義限制類,繼承
BaseThrottle, - 指定從組態檔中要讀取的scope(key),形式為
scope="key"
全域配置:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
}
區域配置:
throttle_classes = [UserRateThrottle]
就比如UserRateThrottle,繼承了SimpleRateThrottle,指定了它所限制的scope,重寫了get_cache_key方法,

原始碼分析
在APIView的initial方法中,三大驗證還剩下最后一個沒有分析,那就是訪問頻率驗證,如下圖:

接下來讓我們查看check_throttles,可以看到,驗證訪問頻率的時候,呼叫的方法為頻率驗證類的allow_request方法,

其中get_throttles用的還是老套路:

示例
自定義一個頻率限制類:
from rest_framework.throttling import BaseThrottle
import time
# 存放訪問記錄(一般放資料庫或者快取中)
VISIT_RECORD = {}
class VisitThrottle(BaseThrottle):
def __init__(self):
self.history = None
def allow_request(self, request, view):
# 1. 獲取用戶ip
remote_addr = request.META.get("REMOTE_ADDR")
# 2. 添加到訪問記錄中
ctime = time.time()
# 當VISIT_RECORD中沒有這個記錄,可以直接訪問,添加一個記錄
if remote_addr not in VISIT_RECORD:
VISIT_RECORD[remote_addr] = [ctime, ]
return True
history = VISIT_RECORD.get(remote_addr)
self.history = history
# 拿到最后歷史記錄里面的最后一個時間,如果最后一個時間小于當前時間-60(一分鐘之前的記錄)
while history and history[-1] < ctime - 60:
history.pop()
if len(history) < 3: # 允許
history.insert(0, ctime)
return True
return False # False表示訪問頻率太高被限制
def wait(self):
"""
還需要等多少秒可以訪問
:return:
"""
ctime = time.time()
return 60 - (ctime - self.history[-1])
注意:官方內置的 SimpleRateThrottle 類中對scope的處理值得一看,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/245523.html
標籤:Python
