源碼
權限組件入口
self.check_permissions(request)
認證細則:
def check_permissions(self, request):
# 遍歷權限對象列表得到一個個權限對象(權限器),進行權限認證
for permission in self.get_permissions():
# 權限類一定有一個has_permission權限方法,用來做權限認證的
# 參數:權限對象self、請求對象request、視圖類對象
# 返回值:有權限返回True,無權限返回False
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
def get_permissions(self):
return [permission() for permission in self.permission_classes]
drf 中的settings.py 中
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny', # 默認的權限認證配置
],
# 根據配置路徑找到 permissions
四個權限類
權限組件自帶的四個權限,默認全局配置的是AllowAny,
- 可以在settings.py中更換全局配置
- 可以在視圖類中針對性的局部配置
- 可以自定義
AllowAny
遊客與登陸用戶都有所有權限
class AllowAny(BasePermission):
# 遊客與登陸用戶都有所有權限
def has_permission(self, request, view):
return True
IsAuthenticated
遊客沒有任何權限,登陸用戶纔有權限
class IsAuthenticated(BasePermission):
# 遊客沒有任何權限,登陸用戶纔有權限
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
IsAdminUser
遊客沒有任何權限,登陸用戶並且是管理員纔有權限
class IsAdminUser(BasePermission):
# 遊客沒有任何權限,登陸用戶並且是管理員纔有權限
def has_permission(self, request, view):
return bool(request.user and request.user.is_staff)
IsAuthenticatedOrReadOnly
認證規則必須是隻讀請求或是合法用戶: 遊客只讀,合法用戶無限制
class IsAuthenticatedOrReadOnly(BasePermission):
# 認證規則必須是隻讀請求或是合法用戶: 遊客只讀,合法用戶無限制
def has_permission(self, request, view):
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
自定義權限類
1) 創建繼承BasePermission的權限類
2) 重寫has_permission方法
3) 實現體根據權限規則 確定有無權限
4) 進行全局或局部配置
認證規則
i.滿足設置的用戶條件,代表有權限,返回True
ii.不滿足設置的用戶條件,代表沒有權限,返回False
使用:
- permissions.py
from rest_framework.permissions import BasePermission
from django.contrib.auth.models import Group
class MyPermission(BasePermission):
def has_permission(self, request, view):
# 只讀接口判斷
r1 = request.method in ('GET', 'HEAD', 'OPTIONS')
# group爲有權限的分組
group = Group.objects.filter(name='管理員').first()
# groups爲當前用戶所屬的所有分組
groups = request.user.groups.all()
r2 = group and groups
r3 = group in groups
# 讀接口大家都有權限,寫接口必須爲指定分組下的登陸用戶
return r1 or (r2 and r3)
- view.py
# 遊客只讀,登錄用戶只讀,只有登錄用戶屬於 管理員 分組,纔可以增刪改
from utils.permissions import MyPermission
class TestAdminOrReadOnlyAPIView(APIView):
permission_classes = [MyPermission] # 局部配置
# 所有用戶都可以訪問
def get(self, request, *args, **kwargs):
return APIResponse(0, '自定義讀 OK')
# 必須是 自定義“管理員”分組 下的用戶
def post(self, request, *args, **kwargs):
return APIResponse(0, '自定義寫 OK')
- settings.py
REST_FRAMEWORK = {
# 權限類配置
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.IsAdminUser',
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
# 全局配置自定義的
'rest_framework.permissions.MyPermission',
],
}