django restframework permission


與 authentication 和 throttling 一起,permission 決定是應該接受還是拒絕訪問請求。
權限檢查總是在視圖的最開始處運行,在任何其他代碼被允許進行之前。權限檢查通常會使用 request.user 和 request.auth 屬性中的認證信息來確定是否允許傳入請求。
權限用於授予或拒絕不同類別的用戶訪問 API 的不同部分。
最簡單的權限是允許通過身份驗證的用戶訪問,並拒絕未經身份驗證的用戶訪問。這對應於 REST framework 中的 IsAuthenticated 類。
稍微寬松的權限會允許通過身份驗證的用戶完全訪問,而未通過身份驗證的用戶只能進行只讀訪問。這對應於 REST framework 中的 IsAuthenticatedOrReadOnly 類。

設置權限策略

默認權限策略可以使用 DEFAULT_PERMISSION_CLASSES setting 全局設置。例如

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

如果未指定,則此設置默認為允許無限制訪問:

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)

當然也可以基於 APIView 類的視圖上設置身份驗證策略

查看源碼,restframework現成的類有7個,介紹如下常用四個

AllowAny:允許無限制訪問

IsAuthenticated :允許訪問任何經過身份驗證的用戶,並拒絕訪問任何未經身份驗證的用戶

IsAdminUser:允許超級用戶訪問

IsAuthenticatedOrReadOnly:對經過身份驗證的用戶的允許完全訪問,但對未經身份驗證的用戶的允許只讀訪問

@six.add_metaclass(BasePermissionMetaclass)
class BasePermission(object):
    """
    A base class from which all permission classes should inherit.
    """

    def has_permission(self, request, view):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

    def has_object_permission(self, request, view, obj):
        """
        Return `True` if permission is granted, `False` otherwise.
        """
        return True

 但完全可以我們自己來寫,僅需要面向上述源碼任意一個接口即可。

apps/app/permissions.py

from rest_framework.permissions import BasePermission


class IsLoginReadOnly(BasePermission):
    """
    自定義權限設置
    """
    def has_permission(self,request,view):

        return all((request.user.is_authenticated,request.user.is_staff))

如果你需要測試請求是讀取操作還是寫入操作,則應該根據常量SAFE_METHODS檢查請求方法,SAFE_METHODS是包含'GET''OPTIONS''HEAD'的元組 

if request.method in permissions.SAFE_METHODS:
    # 檢查只讀請求的權限
else:
    # 檢查讀取請求的權限

  

views.py

from rest_framework import mixins
from rest_framework import viewsets

from .models import UserProfile
from .serializers import UserProfileSerializer
from .permissions import IsAuthenticatedOrReadOnly


class UsersListViewSets(viewsets.GenericViewSet,mixins.ListModelMixin):
    """
    用戶列表
    """
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    permission_classes = (IsAuthenticatedOrReadOnly,)

  

對象級權限

實際場景下,我們往往需要對權限細分:

POST 請求要求用戶對模型實例具有 add 權限。
PUT 和 PATCH 請求要求用戶對模型實例具有 edit 權限。
DELETE 請求要求用戶對模型實例具有 delete 權限。

這就需要我們重寫APIView下的has_permissions方法

views.py

from .permission import UserAddPermission
from .permission import UserDeletePermission
from .permission import UserEditPermission
from .permission import UserQueryPermission

# permission_classes = (UserQueryPermission,)
    def get_permissions(self):
        if self.action == "create":
            self.permission_classes = (UserAddPermission,)
        elif self.action == "list":
            self.permission_classes = (UserQueryPermission,)
        elif self.action == "update":
            self.permission_classes = (UserEditPermission,)
        elif self.action == "destroy":
            self.permission_classes = (UserDeletePermission,)
        return super().get_permissions()

permission.py

class UserAddPermission(BasePermission):
    """
    增加用戶權限
    """
    def has_permission(self, request ,view):
        user = request.user
        if user.is_authenticated:
            permissons = user.has_permissons()
            return "add user" in permissons

 遇到了問題,即使UsersListViewSets繼承了viewsets.ModelViewSet,該接口依舊只允許GET, POST, HEAD, OPTIONS四種方法,

沒有put和delete.

解決:自己手動綁定。。。

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self,request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM