drf三大认证之认证源码解析

1.认证,频率,权限的源码解读入口就是APIView源码的dispatch方法的三大认证,全局异常处理
   self.initial(request, *args, **kwargs)
2.查看APIView的initial里面的三句代码 就是三大认证
        self.perform_authentication(request)   认证
        self.check_permissions(request)        权限
        self.check_throttles(request)          频率
3.查看认证perform_authentication  还是在APIView中
  只返回了一句话:request.user
  这个request就是Request类里的对象,那么由此可以推导user应该是一个方法
4.去Request类里查找user方法
  user方法被@property包装成了属性
   def user(self):
        if not hasattr(self, '_user'):   # 判断self也就是Request对象中是否有user属性
            with wrap_attributeerrors():
                self._authenticate()   # 第一次登录的时候是没有的user的走这个代码
        return self._user  # 如果有的话就返回user  也就是我们认证以后写的reques.user
5.所以我们需要去看Request类里的authenticate方法
  
    def _authenticate(self):
        # 循环我们自己写的认证对象,也就是配置在视图类中的认证类对象列表
        for authenticator in self.authenticators:
            try:
                # 调用认证类对象的authenticate方法
                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

        self._not_authenticated()

6.user_auth_tuple = authenticator.authenticate(self)
 这就是为什么我们在继承了BaseAuthentication以后需要重写authenticate方法
 重写的def authenticate(self, request):传入了两个参数,而源码里只有一个参数的原因是因为源码就是在Request类里面执行的,重写的参数request就是源码里的self
 7.用try检测的代码  如果验证通过返回一个元组 
   user_auth_tuple = authenticator.authenticate(self)
  这里的元组就是我们重写的返回值 return user_token.user, token 一个是当前的登录用户,一个是验证token
  如果不通过则抛异常
    raise AuthenticationFailed('您还没有登录')
8.判断返回值如果不为空的话
  if user_auth_tuple is not None:
    self.user, self.auth = user_auth_tuple   # 给返回值解压赋值
     此时的self.user 就是request.user   self.auth 就是request.auth
       
    如果认证对象列表里有多个值的话,那么当有返回值的时候,直接return结束循环,不再运行后面的认证
posted @ 2022-10-09 21:12  Hsummer  阅读(33)  评论(0编辑  收藏  举报