zoukankan      html  css  js  c++  java
  • (二) rest_framework 认证源码流程与配置

    源码流程:
    dispatch函数执行

    当寻找对应路由的视图函数之前,首先执行 self.initialize_request(request, *args, **kwargs)
    
    # Get the appropriate handler method
       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
           
    # 首先执行 self.initialize_request(request, *args, **kwargs) 
    # rest_framework首选对原始的request对象进行封装,然后返回新的request对象。
     # Request(
     #     request,
     #     authenticators=self.get_authenticators(),
    		...
     # )
    
    

    原来的request对象初始化为:self._request,后面可以通过request._request获取原始request对象
    get_authenticators函数为获取认证类的实例化对象
    self.get_authenticators() = [auth() for auth in self.authentication_classes]
    配置方法:

    1. settings 文件全局配置:api_settings.DEFAULT_AUTHENTICATION_CLASSES
    2. 自定义配置 指定 authentication_classes即可
    其次执行:self.initial(request, *args, **kwargs)
    def initial(self, request, *args, **kwargs):
            ...
            self.perform_authentication(request) # = request.user
    		...
    
    @property
      def user(self):
          if not hasattr(self, '_user'):
              with wrap_attributeerrors():
                  # 进行一层一层认证
                  self._authenticate()
          return self._user
    
    def _authenticate(self):
        for authenticator in self.authenticators:
            try:
                user_auth_tuple = authenticator.authenticate(self) #调用认证类的authenticate方法
            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
    

    自定义认证,继承BaseAuthentication基类,例如:

    class MyAuthentication(BaseAuthentication):
        def authenticate(self, request): 
            token = request._request.GET.get("token")
            if not token:
                raise AuthenticationFailed
            return ('donghao', 'auth auth') #设置到request.user , request.auth
    
        def authenticate_header(self, request):
        	"""
            Return a string to be used as the value of the `WWW-Authenticate`
            header in a `401 Unauthenticated` response, or `None` if the
            authentication scheme should return `403 Permission Denied` responses.
            未认证时,返回浏览器登陆弹窗。提交 类似 “Authorization: Basic YWRtaW46YWRtaW4=”的数据
            """
            return 'Basic realm="api"'
    

    rest_framework已经实现的 BasicAuthentication

    auth = auth = request.META.get('HTTP_AUTHORIZATION', b'').split()
    auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':')
    userid, password = auth_parts[0], auth_parts[2]
    

    匿名用户设置,例如:

        'UNAUTHENTICATED_USER': lambda: '匿名用户',
        'UNAUTHENTICATED_TOKEN': lambda: '匿名auth'
    
  • 相关阅读:
    二分搜索
    Shell 字符串处理、获取文件名和后缀名
    sqlldr使用说明
    Linux cached过高问题
    算法时间复杂度
    #if,#ifdef,#ifndef的区别
    memcpy momove strcmp源码实现
    怎么解决/bin/sh: arm-linux-gcc: not found make
    性能文章
    linux
  • 原文地址:https://www.cnblogs.com/donghaoblogs/p/12435354.html
Copyright © 2011-2022 走看看