天天看點

DRF 3.x Permissions 權限使用示例和配置方法

作者:Mr資料楊

正常網站開發的情況下,使用者的身份驗證或識别本身出現問題是無法進行通路資訊或代碼。

基于 DFR 進行權限的設定可以設定身份認證和權限組合使用,用來确定請求是否傳回資料還是拒絕請求資料。

雖然身份驗證是檢查使用者身份的過程(請求來自的使用者所簽署的令牌),但授權是檢查請求使用者是否具有執行請求的必要權限的過程。

DRF 中的授權過程由權限覆寫。

DRF 3.x Permissions 權限使用示例和配置方法

Permissions 權限

權限檢視方法

check_permissions根據請求資料檢查是否應允許請求。

class APIView(View):
    def check_permissions(self, request):
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request,
                    message=getattr(permission, 'message', None),
                    code=getattr(permission, 'code', None)
                )           

check_object_permissions根據請求和對象資料的組合檢查是否應允許請求。

class APIView(View):
    def check_object_permissions(self, request, obj):
        for permission in self.get_permissions():
            if not permission.has_object_permission(request, self, obj):
                self.permission_denied(
                    request,
                    message=getattr(permission, 'message', None),
                    code=getattr(permission, 'code', None)
                )           

check_permissions 在執行視圖處理程式之前調用,而check_object_permissions 不會執行。

class XXXXAPI(APIView):
    def get(self, request, pk):
        data= get_object_or_404(data.objects.all(), pk=pk)
        self.check_object_permissions(request, data) 
        serializer = MessageSerializer(data)
        return Response(serializer.data)           

權限檢視

運作視圖前檢查每個請求的權限,如果檢查失敗則會引發 exceptions.PermissionDenied 異常并且不會運作視圖代碼。

  • 401:請求未成功進行身份驗證。
  • 403:請求已成功通過身份驗證,,但權限被拒絕禁止的響應。
def get_object(self):
    obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
    self.check_object_permissions(self.request, obj)
    return obj           

認證的基礎方式

  1. IsAuthenticated,允許已認證并通過認證的使用者情況可以進行後續操作。
  2. IsAdminUser,使用者身份中 user.is_staff 是 True 被允許。
  3. IsAuthenticatedOrReadOnly,允許已認證使用者讀取和修改,未認證使用者隻讀。

權限政策設定

settings.py 進行權限配置。

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',# IsAuthenticated 僅通過認證的使用者
        'rest_framework.permissions.AllowAny', # AllowAny 允許所有使用者
        'rest_framework.permissions.IsAdminUser',# IsAdminUser 僅管理者使用者
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',  # IsAuthenticatedOrReadOnly 認證的使用者可以完全操作,否則隻能get讀取
    ]
}           

視圖應用

views.py 普通中設定權限方法。

from rest_framework.permissions import *
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = [IsAuthenticated|IsAuthenticatedOrReadOnly]

    def get(self, request, format=None):
        content = {
            'status': 'request 被允許'
        }
        return Response(content)           

views.py 裝飾器設定權限方法。

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)           
DRF 3.x Permissions 權限使用示例和配置方法

其他權限類型

權限類型 DjangoModelPermissions

該權限類與 Django 的标準 django.contrib.auth 模型權限相關聯,隻能應用于 .queryset 屬性的視圖。

僅當使用者通過身份驗證并配置設定了相關的模型權限時,才會授權。

  • POST 請求需要使用者對 add 模型具有權限。
  • PUT、PATCH 請求要求使用者對 change 模型具有權限。
  • DELETE 請求需要使用者對 delete 模型具有權限。

DjangoModelPermissionsOrAnonReadOnly

與 DjangoModelPermissions 相似,允許未經身份驗證的使用者對 API 進行隻讀通路。

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
      'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}           

DjangoObjectPermissions

與 DjangoModelPermissions 相似,該權限類與 Django 的标準對象權限架構相關聯,允許對模型進行按對象劃分的權限,使用此權限類需要添加一個支援對象級權限的權限後端 django-guardian。

将 django-guardian 用作對象級權限後端需要考慮使用 djangorestframework-guardian 包提供的DjangoObjectPermissionsFilter 類確定清單端點隻傳回結果。

安裝三方插件。

pip install django-guardian           

settings.py 中添加配置應用。

INSTALLED_APPS = [
    ......
    'guardian',
]

# guardian作為額外的授權BACKEND添加進配置
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'guardian.backends.ObjectPermissionBackend',
)           

生成表單guardian_groupobjectpermission和guardian_userobjectpermission,用于記錄了使用者/組與model以及model内的具體object的權限對應關系。

python manage.py migrate           

權限的自定義舉例

自定義權限需要重寫 BasePermission 。

  • .has_permission(self, request, view)
  • .has_object_permission(self, request, view, obj)

方法應傳回 True 應授予請求通路權限, 否則則傳回 False。

class MyPermission(BasePermission):
    message = '自定義的傳回資訊'

    def has_permission(self, request, view):  # 清單資料
        # # 這個函數傳回True或者False,True表示有權限,False表示沒有權限,這個函數同時有三個參數,最後一個是view, 這個是在源碼中規定的
        # if request.user.id == 0:
        #     return False
        # else:
        return True

    def has_object_permission(self, request, view, obj):  # 對象資料
        """使用者是否有權限通路添加了權限控制類的資料對象"""
        # 需求:使用者能夠通路id為1,3的對象,其他的不能夠通路
        if request.user.is_active == 1:
            return True
        else:
            return False           
DRF 3.x Permissions 權限使用示例和配置方法

繼續閱讀