以这个url为例:
path('api/v1/order/',views.orderView.as_view()),
我们只有一个get方式,那么请求进来先去执行 self.dispatch,我们没有写(覆盖),就去父类(继承与APIView)执行
class orderView(APIView): """ 用于处理订单相关业务 """ authentication_classes = [Authtication,] #DEFAULT_PERMISSION_CLASSES默认去配置文件找,这里自定义一个 def get(self,request,*args,**kwargs): ret = {'code':1000,'msg':None,'data':None} try: ret['data'] = ORDER_DISK except Exception as e: pass return JsonResponse(ret)
也就是说第一步执行APIView中有中的dispatch。dispatch内部流程:
-
对request进行封装。
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs) #封装request
self.request = request
self.headers = self.default_response_headers # deprecate?
1.1封装(封装了authenticators)部分代码:
-
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), #这里封装了一个authenticators,调用get_get_authenticators()。我们views中没有定义,那么继续在父类中找。 negotiator=self.get_content_negotiator(), parser_context=parser_context )
- 1.2:get_authenticators,内部是一个列表生成式,
-
def get_authenticators(self): """ Instantiates and returns the list of authenticators that this view can use. """ return [auth() for auth in self.authentication_classes] #self.authentication_classes我们views也没有定义,所以还是去父类中找,
1.3.self.authentication_classes定义 authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES,指向配置文件:api_settings的DEFAULT_AUTHENTICATION_CLASSES。
也就是说DEFAULT_AUTHENTICATION_CLASSES默认是在配置文件中,如果我们在views中设置了,那么就会覆盖掉。直接用我们自定义的。
class Authtication(object): def authenticate(self,request): #user_auth_tuple = authenticator.authenticate(self)跟踪得到,默认调用authenticate方法,返回一个元组 token = request._request.GET.get('token') token_obj = models.UserToken.object.filter(token=token).first() if not token_obj: raise exceptions.APIException('用户认证失败') return (token_obj.user,token_obj.token) def authenticate_header(self,request): '这个方法暂时不知道干啥,不加保存,加上不用先' pass
2、调用initial(进行认证)
2.1、进入initial内部看看执行了什么
def initial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """ self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted self.perform_authentication(request) #第一个执行了perform_authentication传入了刚才包装好的request self.check_permissions(request) self.check_throttles(request)
2.2 self.perform_authentication(request)内部调用了 request.user:
def perform_authentication(self, request): """ Perform authentication on the incoming request. Note that if you override this and simply 'pass', then authentication will instead be performed lazily, the first time either `request.user` or `request.auth` is accessed. """ request.user #这里为啥没有括号。。。。
现在手动去到 request.user:内部又调用了self._authenticate()
@property def user(self): """ Returns the user associated with the current request, as authenticated by the authentication classes provided to the request. """ if not hasattr(self, '_user'): with wrap_attributeerrors(): self._authenticate() return self._user
最后进入self._authenticate()。循环self.authenticators,这个不就是上一步封装的那个认证类列表,也就是我们views中定义(覆盖)的那个列表。再看内部的方法每个类必须有一个authenticate方法。返回要给元组,
def _authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. """ for authenticator in self.authenticators: try: #执行封装好的认证类的authenticate方法, #如果这个方法抛出异常,这里except exceptions.APIException就可以抛出异常raise又再向上抛出异常 #1如果又返回值,则执行下面if user_auth_tuple is not None:,把元组的值赋值给,user,auth,如果认证成功下面直接return,结束循环, #如果没有返回值,跳过循环,进入下一次循环认证。 #如果都没有返回值,那么执行,self._not_authenticated() 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()
返回的元组:那么我们就可以自定义个这个类,也返回一个元组。(user,token)
def authenticate(self, request): return (self.force_user, self.force_token)
如果没有返回值,执行到了self._not_authenticated(),源代码这样:
def _not_authenticated(self): """ Set authenticator, user & authtoken representing an unauthenticated request. Defaults are None, AnonymousUser & None. """ self._authenticator = None #如果UNAUTHENTICATED_USER存在那么久把self。user的值调用配置文件UNAUTHENTICATED_USER,这里去到配置文件可以看到是一个django.contrib.auth.models.AnonymousUser #也就是说默认赋值,匿名用户 if api_settings.UNAUTHENTICATED_USER: self.user = api_settings.UNAUTHENTICATED_USER() else: self.user = None #token也是跟上面一个取配置文件,'UNAUTHENTICATED_TOKEN': None, if api_settings.UNAUTHENTICATED_TOKEN: self.auth = api_settings.UNAUTHENTICATED_TOKEN() else: self.auth = None