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继续下个认证
posted @ 2019-11-22 20:10  corei5tj  阅读(110)  评论(0编辑  收藏  举报