REST framework rights management source analysis

REST framework rights management source analysis

Like authentication, dispatch () as an inlet, from self.initial(request, *args, **kwargs)enteringinitial()

    def initial(self, request, *args, **kwargs):
        # .......
        # 用户认证
        self.perform_authentication(request)
        # 权限控制
        self.check_permissions(request)
        # ...

check_permissions()Rights management is the source of the entrance

    # 权限管理
    def check_permissions(self, request):
        """
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        """
        for permission in self.get_permissions():
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, 'message', None)
                )

And user authentication, same as traversing a list of objects class privilege, and the list of elements calling has_permission()method, which returns a Boolean value, Truerepresentatives of authority, Falserepresentatives do not have permission.

    def get_permissions(self):
        return [permission() for permission in self.permission_classes]

If you do not have permission to callpermission_denied()

    def permission_denied(self, request, message=None):
        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated()
        raise exceptions.PermissionDenied(detail=message)

If the authentication framework of REST (authentication_classes array is not empty) and authentication fails, throw NotAuthenticated an exception, otherwise it will throw PermissionDenied an exception

class NotAuthenticated(APIException):
    status_code = status.HTTP_401_UNAUTHORIZED
    default_detail = _('Authentication credentials were not provided.')
    default_code = 'not_authenticated'

NotAuthenticated will lead to a 401 error (lack of user credentials)

class PermissionDenied(APIException):
    status_code = status.HTTP_403_FORBIDDEN
    default_detail = _('You do not have permission to perform this action.')
    default_code = 'permission_denied'

The PermissionDenied will return error 403 (unauthorized access denial)

At the permission_denied()time of delivery class parameters, the use of reflection

self.permission_denied(
                    request, message=getattr(permission, 'message', None)
                )

Will seek rights in this class object messageproperties, did not find it to use None, and this parameter will only be used later on PermissionDenied exceptions that inherit from APIException, and in APIException constructor, the parameter is an exception can be found in detail description and definition of message attributes in their class privileges can be changed after describing authentication failure

class APIException(Exception):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    default_detail = _('A server error occurred.')
    default_code = 'error'

    def __init__(self, detail=None, code=None):
        if detail is None:
            detail = self.default_detail
        if code is None:
            code = self.default_code
    # ...

Examples

# api/utils/Permission.py
from rest_framework.permissions import BasePermission


class CommonPermission(BasePermission):
    """
    普通用户权限,作用于全局
    """
    def has_permission(self, request, view):
        print(request.user)
        if request.user.user_type == 1:
            return True

    def has_object_permission(self, request, view, obj):
        """
        一旦获得View权限,将获得所有object权限
        :return: True
        """
        return True


class VipPermission(BasePermission):
    """
    VIP 用户权限
    """
    message = '您首先要称为VIP才能访问'
    
    def has_permission(self, request, view):
        print(request.user)
        if request.user.user_type == 2:
            return True

    def has_object_permission(self, request, view, obj):
        return True

# api/view.py
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
from api.utils.Permission import VipPermission


class LoginView(APIView):
    authentication_classes = []
    # 登录无需权限认证
    permission_classes = []

    def post(self, request, *args, **kwargs):
        pass


@method_decorator(csrf_exempt, name='dispatch')
class ShopView(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse(request.user.username)

    def post(self, request, *args, **kwargs):
        return HttpResponse('POST')



class VipIndexView(APIView):
    """
    只授权给VIP用户查看
    """
    permission_classes = [VipPermission]

    def get(self, *args, **kwargs):
        return JsonResponse("welcome VIP ", safe=False)

# RESTdemo.setting.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.MyAuthentication.MyAuthentication'],
    'UNAUTHENTICATED_USER': None,
    'UNAUTHENTICATED_TOKEN': None,
    'DEFAULT_PERMISSION_CLASSES': ['api.utils.Permission.CommonPermission']
}
Published 62 original articles · won praise 33 · views 10000 +

Guess you like

Origin blog.csdn.net/zjbyough/article/details/102978912