(二) 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]
配置方法:

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'

相关内容

    暂无相关文章

评论关闭