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方法


浙公网安备 33010602011771号