• drf(三)—权限控制


    drf(三)—权限控制

    问题引出:有些功能(数据)是需要具备一定权限的的用户才能进行访问,例如:VIP才有查看某些数据的功能。

    上节内容的补充:

    • def _authenticate(self):
          for authenticator in self.authenticators: #循环配置文件中的列表认证
              try:
                  user_auth_tuple = authenticator.authenticate(self)
              except exceptions.APIException:
                  self._not_authenticated()
                  raise # 抛出错误
      
              if user_auth_tuple is not None:
                  self._authenticator = authenticator
                  self.user, self.auth = user_auth_tuple
                  return # 函数终止,对象啊中封装元组
              # 本次循环无返回。
      

      说明:上述情况的三种返回值

      # 1、无返回值 None
      表示本次循环中认证组件不产生任何作用,会进行到下一个循环,表示配置文件中列表可以有多个认证对象
      
      # 2、抛出异常
      raise "认证失败"
      
      # 3.函数终止,对象啊中封装元组
      两个值 self.user,self.auth
      

    1.源码分析

    • 与认证类似,权限与认证流程相似,因为请求都要经过dispatch

      def dispatch(self, request, *args, **kwargs):
          self.args = args
          self.kwargs = kwargs
          request = self.initialize_request(request, *args, **kwargs)
          self.request = request
          self.headers = self.default_response_headers  # deprecate?
          try:
              self.initial(request, *args, **kwargs) #进入功能
              if request.method.lower() in self.http_method_names:
                  handler = getattr(self, request.method.lower(),
                                    self.http_method_not_allowed)
              else:
                  handler = self.http_method_not_allowed
              response = handler(request, *args, **kwargs)
          except Exception as exc:
              response = self.handle_exception(exc)
          self.response = self.finalize_response(request, response, *args, **kwargs)
          return self.response
      
    • initial()函数

      def initial(self, request, *args, **kwargs):
          self.format_kwarg = self.get_format_suffix(**kwargs)
          neg = self.perform_content_negotiation(request)
          request.accepted_renderer, request.accepted_media_type = neg
      
          version, scheme = self.determine_version(request, *args, **kwargs)
          request.version, request.versioning_scheme = version, scheme
      
          self.perform_authentication(request) #认证功能
          self.check_permissions(request) # 权限控制功能
          self.check_throttles(request)
      
    • check_permissions()函数

      def check_permissions(self, request):
          for permission in self.get_permissions():# 循环该对象
              if not permission.has_permission(request, self):
                  # 不存在验证方法直接进入到下一个类的验证。
                  # 表示定义的权限类中应该具备一个方法 has_permission()
                  self.permission_denied(
                      request,
                      message=getattr(permission, 'message', None),
                      code=getattr(permission, 'code', None)
                      # 本类不存在使用反射进行获取,两个变量
                  )
      
    • get_permissions()函数

      def get_permissions(self):
      	# 返回列表生成式,循环生成并存储对象。
          return [permission() for permission in self.permission_classes]
      

      image-20220406221308882

    • permission_denied()函数

      def permission_denied(self, request, message=None, code=None):
          if request.authenticators and not request.successful_authenticator:
              # 如果未认证,或认证失败则抛异常
              raise exceptions.NotAuthenticated()
          raise exceptions.PermissionDenied(detail=message, code=code)
      
    • PermissionDenied类

      class PermissionDenied(APIException):
          status_code = status.HTTP_403_FORBIDDEN
          default_detail = _('You do not have permission to perform this action.')
          default_code = 'permission_denied'
          # 可以实现定制报错消息。
      

    2.简单使用(局部)

    class SimplePermission(object):
        def has_permission(self,request,*args,**kwargs):
            # 返回 True 可以访问
            #if request.user.user_type != 3:
            #     return False # 返回False无权访问;
            return False
    

    定义视图

    class OrderView(APIView):
        permission_classes=[SimplePermission,]# 局部使用权限控制器
        def get(self,*args,**kwargs):
            return JsonResponse(ORDER_DICT)
    

    image-20220407080344399

    class SimplePermission(object):
        message="您没有权限访问!"# 定义返回没有权限的信息
        def has_permission(self,request,*args,**kwargs):
            # 返回 True 可以访问
            # if request.user.user_type != 3:
            #     return False # 返回False无权访问;
            return False
    

    image-20220407081205063

    3.内置权限及全局使用

    # BasePermission源码,
    class BasePermission(metaclass=BasePermissionMetaclass):
        """
        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
    

    我们自定义的权限类中一般需要自定义类中继承该类。

    使用:

    class MyPermission(BasePermission):
        # 继承BasePermission
        message="您没有权限访问!!!"
        def has_permission(self, request, view):
            if request.user.user_type!=3:
                return False
            return True
    
    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":['app01.utils.auth.MyAuthentication',],
        "UNAUTHENTICATED_USER":None, # 匿名,request.user = None
        "UNAUTHENTICATED_TOKEN":None,
        
        # 权限配置
        "DEFAULT_PERMISSION_CLASSES":['app01.utils.permission.MyPermission',],
    }
    

    注意:当配置了全局的权限控制函数后需要在登录窗口中设置权限,permission_classes = []

    使用SVIP用户进行查看

    image-20220407082057868

    普通用户进行查看

    image-20220407082526944

    继续努力,终成大器!!

  • 相关阅读:
    Github注册过程以及对管理软件的了解
    进度总结
    总体心得
    学车后的领悟
    打工心得
    关于传统文化的对话实践计划书
    软件工程-课程总结
    结对编程项目---四则运算
    作业三
    目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点
  • 原文地址:https://www.cnblogs.com/Blogwj123/p/16110666.html
Copyright © 2020-2023  润新知