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结束循环,不再运行后面的认证