一、許可權

許可權可以限制使用者對檢視的訪問和對具體資料物件的訪問。

  • 在執行檢視的dispatch方法前,會先進行檢視訪問許可權的判斷
  • 在通過get_object獲取物件時,會進行模型物件訪問許可權的判斷

原始碼分析

核心原始碼——>APIView——>dispatch——>initial——>self.check_permissions(request)

def check_permissions(self, request):

    # 遍歷許可權物件列表得到一個個許可權物件(許可權器),進行許可權認證
for permission in self.get_permissions(): # 許可權類一定要有一個has_permission許可權方法,用來做許可權認證的
# 引數:許可權物件self、請求物件request、檢視類物件view
"""
has_permission(self, request, view):
"""
# 返回值:有許可權返回True、無許可權返回False
if not permission.has_permission(request, self):
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)

許可權使用

寫一個類,繼承BasePermission,重寫has_permission,如果許可權通過,就返回True,不通過就返回False。

from rest_framework.permissions import BasePermission

class UserPermission(BasePermission):
def has_permission(self, request, view):
# 由於已經認證過了,request內就已經有了user物件了,當前使用者 user = request.user # 當前登入使用者
# 如果該欄位用了choice,那麼可以使用get_欄位名_display(),取出choice後面的中文
print(user.get_user_type_display()) if user.user_type == 1: # 不是超級使用者不能訪問
return True
else:
return False

如何使用:

# 區域性使用
from app01.app01_auth import UserPermission class TestView(APIView):
authentication_classes = [TokenAuthentication] # 認證配置
permission_classes = [UserPermission] # 許可權配置 # 全域性使用
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":[
"app01.app01_auth.TokenAuthentication", # 全域性認證配置
],
'DEFAULT_PERMISSION_CLASSES': [
'app01.app01_auth.UserPermission', # 全域性許可權配置
],
} # 區域性禁用 settings.py
class TestView(APIView):
permission_classes = [] # 區域性禁用許可權配置

內建許可權

內建許可權類

from rest_framework.permissions import AllowAny,IsAuthenticated,IsAdminUser,IsAuthenticatedOrReadOnly

- AllowAny 				允許所有使用者
- IsAuthenticated 僅通過認證的使用者
- IsAdminUser 僅管理員使用者
- IsAuthenticatedOrReadOnly 已經登陸認證的使用者可以對資料進行增刪改操作,沒有登陸認證的只能檢視資料。

如何使用

# 1 建立超級管理員	>>python manage.py createsuperuser

from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication
class TestView(APIView):
authentication_classes=[SessionAuthentication,]
permission_classes = [IsAdminUser]
def get(self,request,*args,**kwargs):
return Response('這是測試資料,超級管理員可以看')
# 3 超級使用者登入到admin,再訪問test就有許可權
# 4 正常的話,普通管理員,沒有許可權看(判斷的是is_staff欄位)

二、頻率

可以用來減輕伺服器壓力,對介面訪問的頻率進行限制

內建頻率限制

由於大部分需求使用內建的頻率限制就已經可以了,所以主要看看內建的頻率限制

限制未登入使用者:AnonRateThrottle

也就是限制所有匿名未認證使用者,使用IP區分使用者。anon設定頻次

# 全域性使用 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '5/m', # 每分鐘訪問次數
}
} # views.py
from rest_framework.views import APIView class TestView(APIView): def get(self, request):
return Response('我是未登入使用者,每分鐘只能訪問5次') # ------------------------------------------------------------------- # 區域性使用
# 還是需要先在settings.py中配置訪問次數
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'anon': '5/m',
}
} # views.py
from rest_framework.throttling import AnonRateThrottle
from rest_framework.views import APIView class TestView(APIView):
throttle_classes = [AnonRateThrottle] # 區域性使用 def get(self, request):
return Response('我是未登入使用者,每分鐘只能訪問5次')

限制登入使用者:UserRateThrottle

需求:未登入使用者1分鐘訪問5次,登入使用者一分鐘訪問10次

對認證使用者限制,使用User id 來區分,user 設定頻次

但是這個有侷限性,它只能是auth_user表,admin這套系統才能使用

# 全域性使用 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle', # 未登入使用者
'rest_framework.throttling.UserRateThrottle' # 登入使用者
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m', # 登入使用者頻率
'anon': '5/m', # 未登入使用者頻率
}
} from rest_framework.views import APIView class TestView(APIView): def get(self, request):
return Response('未登入使用者5次,登入之後10次')

IP頻率限制:SimpledRateThrottle

限制使用者對於每個檢視的訪問頻率,使用IP限制

# 1、寫一個類,繼承SimpleRateThrottle,重寫 get_cache_key
# app01_auth.py
from rest_framework.throttling import SimpleRateThrottle class App01_Throttle(SimpleRateThrottle):
scope = 'luffy' def get_cache_key(self, request, view):
# 返回什麼原始碼中的key就是什麼
return request.META.get('REMOTE_ADDR') # 2、全域性配置頻率次數 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'luffy': '5/m' # key要根據類中的scope對應
},
} # 3、區域性使用 views.py
from rest_framework.views import APIView
from app01.app01_auth import App01_Throttle class TestView(APIView):
throttle_classes = [App01_Throttle] # 區域性使用配置 def get(self, request):
return Response('IP限制每分鐘訪問5次') # 全域性使用需要在settings.py配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'app01.app01_auth.App01_Throttle', # 全域性及配置
),
'DEFAULT_THROTTLE_RATES': {
'luffy': '5/m' # key要根據類中的scope對應
},
}