一、許可權
許可權可以限制使用者對檢視的訪問和對具體資料物件的訪問。
- 在執行檢視的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對應
},
}