• djangorestframework的源码认证流程


    1.APIView的大致执行流程

    由于请求首先经过dispatch,所以我们写的CBV 首先要去找dispatch,自己写的没有要去父类APIView找
    例:
    class
    OrderView(APIView): #authentication_classes = [MyAuthentications, ] def get(self, request, *args, **kwargs): self.dispatch print(request) ret = { 'code': 1000, 'msg': 'sdfa' } return HttpResponse(json.dumps(ret), status=201) def post(self, request, *args, **kwargs): return HttpResponse('创建订单')
    在APIView中找到dispatch

     

    上面代码中self.dispatch快速找到dispatch方法

    #上述中的大致步骤为
    1.对request进行加工
    2.(1)处理版权信息
      (2)认证
      (3)权限  
      (4)频率限制
    3.执行 get/post/put/delete函数,此request为加工后的request
    4.对返回结果再次进行加工

    2.接下来是Djangorestframework 的认证流程

    1.封装request
    #对原生的request进行加工
            #return Request( request,
                   #封装了原生request,
                   parsers=self.get_parsers(),
                   authenticators=self.get_authenticators(),
                   negotiator=self.get_content_negotiator(),
                   parser_context=parser_context)
    #现在我们对request进行了两个操作(原生request,[BasicAuthentication(),]) request = self.initialize_request(request, *args, **kwargs) #获取原生requests,request._requests #获取认证类的对象,request.authenticators self.request = request self.headers = self.default_response_headers # deprecate? #进入initalize_request def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, #封装了原生request parsers=self.get_parsers(), #[BasicAuthentication(),] #实例化对象 authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context ) #这里封装了原生request、认证、版本控制、上下文解析等方法 def get_authenticators(self): """ Instantiates and returns the list of authenticators that this view can use. """ return [auth() for auth in self.authentication_classes] #实例化
    •   若想要调用APIView中的方法,ctrl+Request 到request.py中
      •    self._request = request
            self.parsers = parsers or ()
            self.authenticators = authenticators or ()
            self.negotiator = negotiator or self._default_negotiator()
            self.parser_context = parser_context
            self._data = Empty
            self._files = Empty
            self._full_data = Empty
            self._content_type = Empty
            self._stream = Empty
            例:request._request.POST.get('username')
    #2.认证
        def initial(self, request, *args, **kwargs):
            """
            Runs anything that needs to occur prior to calling the method handler.
            """
            self.format_kwarg = self.get_format_suffix(**kwargs)
    
            # Perform content negotiation and store the accepted info on the request
    
            #下两行做版本处理的
            neg = self.perform_content_negotiation(request)
            request.accepted_renderer, request.accepted_media_type = neg
    
            # Determine the API version, if versioning is in use.
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    
            # Ensure that the incoming request is permitted
            #4.实现认证
            # 含原生的以及认证
            self.perform_authentication(request)
    
            #做频率限制的
            self.check_permissions(request)
            self.check_throttles(request)
    #ctrl 进入我们实现认证的方法  perform_authentication
        def perform_authentication(self, request):
            """
            Perform authentication on the incoming request.
    
            Note that if you override this and simply 'pass', then authentication
            will instead be performed lazily, the first time either
            `request.user` or `request.auth` is accessed.
            """
            request.user  #这里的request是APIView的,执行request的user

    @property
        def user(self):
            """
            Returns the user associated with the current request, as authenticated
            by the authentication classes provided to the request.
            """
            if not hasattr(self, '_user'):
                with wrap_attributeerrors():
                    #获取对象认证,进行一步步的认证
                    self._authenticate()
            return self._user



    #执行self._authenticate() 开始用户认证,如果验证成功后返回元组: (用户,用户Token) def _authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. """ #[BasicAuthentication对象] #循环对象列表 for authenticator in self.authenticators: try: #执行对象的authentication方法 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 #返回一个元祖,user、auth return
    #如果认证成功,执行_authenticate方法,若认证失败抛出异常调用self._not_authenticated()
         def _not_authenticated(self):
            """
            Set authenticator, user & authtoken representing an unauthenticated request.
    
            Defaults are None, AnonymousUser & None.
            """
            #如果跳过了所有认证,默认用户和Token和使用配置文件进行设置
            self._authenticator = None
    
            if api_settings.UNAUTHENTICATED_USER:
                self.user = api_settings.UNAUTHENTICATED_USER()
            else:
                self.user = None
    
            if api_settings.UNAUTHENTICATED_TOKEN:
                self.auth = api_settings.UNAUTHENTICATED_TOKEN()
            else:
                self.auth = None

    例子:自定义认证类

    class MyAuthentications(object):
        def authenticate(self, request):
            token = request._request.GET.get('token')
            print(token)
            if not token:
                raise exceptions.AuthenticationFailed('用户认证失败')
            return ('xinzong', None)
    
        def authenticate_header(self, val):
            pass
    
    
    class OrderView(APIView):
        authentication_classes = [MyAuthentications, ]
    
        def get(self, request, *args, **kwargs):
            self.dispatch
            print(request)
            ret = {
                'code': 1000,
                'msg': 'sdfa'
            }
            return HttpResponse(json.dumps(ret), status=201)
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('创建订单')

    效果图:

    未带token

    携带token

  • 相关阅读:
    IIS中的 Asp.Net Core 和 dotnet watch
    net Core 2.0应用程序发布到IIS
    PHP是.NET上的一门开发语言
    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用
    如何快速处理线上故障
    程序员的“认知失调”
    怎么轻松学习JavaScript
    Android-完全退出当前应用程序的四种方法
    Android java.lang.ClassCastException
    Intent传递对象的两种方法(Serializable,Parcelable)
  • 原文地址:https://www.cnblogs.com/u-damowang1/p/13554143.html
Copyright © 2020-2023  润新知