zoukankan      html  css  js  c++  java
  • drf源码分析系列---认证

    认证的使用

    from rest_framework.authentication import BaseAuthentication
    from api import models
    # 认证类
    class TokenAuthentication(BaseAuthentication):
        def authenticate(self, request):
            token = request.query_params.get('token')
            user_object = models.UserInfo.objects.filter(token=token).first()
            if user_object:
                return (user_object, token)
            return (None, None)
        
    # 认证类的应用
    # 单独的视图认证应用
    class OrderView(APIView):
        authentication_classes = [MyAuthentication, ]  #设置成空列表代表没有权限
        def get(self,request,*args,**kwargs):
            print(request.user)
            print(request.auth)
            return Response('order')
        
    # 认证的全局应用
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES"=["api.views.auth.MyAuthentication",]
    }
    

    认证的源码分析

    执行流程

    1.请求进来执行dispatch方法中的initialize_request方法
        def initialize_request(self, request, *args, **kwargs):
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    #会对request对象进行重新封装,把老的request封装成新的request
    执行self.get_authenticators()
        def get_authenticators(self):
            return [auth() for auth in self.authentication_classes]  # 循环自定义的认证类,生成认证对象列表封装到request中
    authentication_classes
    settings中的认证配置
    "DEFAULT_AUTHENTICATION_CLASSES":["api.views.auth.MyAuthentication]
    
    2.执行inital
        def initial(self, request, *args, **kwargs):
    		.......略过的代码
            version, scheme = self.determine_version(request, *args, **kwargs)
            request.version, request.versioning_scheme = version, scheme
    
            self.perform_authentication(request) #认证函数
            self.check_permissions(request)
            self.check_throttles(request)
    
    3.执行perform_authentication(request)认证函数
        def perform_authentication(self, request):
    
            request.user# 调用request的user方法
    
    4.
    @property
        def user(self):
            if not hasattr(self, '_user'):
                with wrap_attributeerrors():
                    self._authenticate()
            return self._user
    
    5.执行_authenticate()方法
        def _authenticate(self):
    
            for authenticator in self.authenticators:
                try:
                    user_auth_tuple = authenticator.authenticate(self) #每个认证对象(authenticator)中的authenticate方法,可以重写该方法进行定制,之前已经封装到request中了
                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,auth)代表认证成功
    #抛出异常代表认证失败
    #返回None继续下个认证
    

    看张图吧!

    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .

    正经点......

    概括

    1.请求进来时,先执行dispatch方法,对的request进行重新封装
    2.执行get_authenticators(),循环authentication_classes得到这个认证类的对象,把对象也封装进去
    3.执行initial中的perform_authentication(request),调用request.user,调用request的user方法(静态属性)
    4.执行 _authenticate,循环authentication对象,调用authenticate方法返回元祖(user,auth)代表认证成功或者抛出异常代表认证失败或返回None继续下个认证
    
  • 相关阅读:
    装饰器的写法以及应用环境
    面向对象中super的作用
    os与sys模块的作用与常用方法
    python re模块
    python 冒泡排序,二分法
    正则表达式
    python 高阶内置函数
    python 内置函数
    python 生成器和生成器表达式
    python 函数名的应用(第一类对象),闭包,迭代器
  • 原文地址:https://www.cnblogs.com/tangjian219/p/11913835.html
Copyright © 2011-2022 走看看