drf 认证组件分析

drf 的APIview 重写了dispatch方法,在下方会执行认证模块

 

initial 方法:

 

进入perform_authentication 方法中(注意:此时的request为apiview包装后的request对象):

 

 然后去drf的Request中寻找user属性或者方法(注意:setter在设置值的时候执行)调用authenticate方法

 然后进入authenticate方法中:

 

 核心代码:

def _authenticate(self):
  # 遍历拿到一个个认证器,进行认证
  # self.authenticators配置的一堆认证类产生的认证类对象组成的 list
  #self.authenticators 你在视图类中配置的一个个的认证类:authentication_classes=[认证类1,认证类2],对象的列表
  for authenticator in self.authenticators:
  try:
    # 认证器(对象)调用认证方法authenticate(认证类对象self, request请求对象)
    # 返回值:登陆的用户与认证的信息组成的 tuple
    # 该方法被try包裹,代表该方法会抛异常,抛异常就代表认证失败
    user_auth_tuple = authenticator.authenticate(self) #注意这self是request对象
   except exceptions.APIException:
    self._not_authenticated()
    raise

  # 返回值的处理
  if user_auth_tuple is not None:
  self._authenticator = authenticator
  # 如何有返回值,就将 登陆用户 与 登陆认证 分别保存到 request.user、request.auth
  self.user, self.auth = user_auth_tuple
  return
  # 如果返回值user_auth_tuple为空,代表认证通过,但是没有 登陆用户 与 登陆认证信息,代表游客
  self._not_authenticated()

authenticators 为__init__实例化时传入的参数  在APIview中调用

 

 进入该方法发现是一个列表生成式: 

 

 

 

 

 

 

 

 

在APIview中查找authentication_classes 为默认配置项:

 

 综上所述,这个地方会拿到配置的认证类的authenticate方法进行认证 这个方法返回俩个值(user和auth)

 

 下一步进行返回值的处理,最终user 给了request对象的user,也就是说用户经过认证就可以使用request.user拿到当前用户对象

 

 所以我们写认证类的时候只需要重写 authenticated 方法,认证成功返回俩值(user,auth) 认证不通过则抛出异常 然后配置在视图中 就可以实现局部认证了,想要所有视图都启用认证则在setting全局文件中配置即可

rest_framework.authentication中有提供的认证父类,规定了子类必须重写authenticate方法

 

posted @ 2021-05-03 21:18  ꧁ℳℓ♛ℓℳ꧁  阅读(65)  评论(0)    收藏  举报