drf源码剖析----认证

点击查看代码
class Request:

    def __init__(self, request, authenticators=None):
        self._request = request
        self.authenticators = authenticators or ()

    @property
    def user(self):
     # 类Request()中没有'_user',访问self._authenticate()
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

    def _authenticate(self):
        # 依次执行认证类对象的authenticate()方法,即类MyAuthentication()的方法
        for authenticator in self.authenticators:
            try:
                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()

    def _not_authenticated(self):
        self._authenticator = None

        if api_settings.UNAUTHENTICATED_USER:
            self.user = api_settings.UNAUTHENTICATED_USER()
        else:
            self.user = None

        if api_settings.UNAUTHENTICATED_TOKEN:
            self.auth = api_settings.UNAUTHENTICATED_TOKEN()
        else:
            self.auth = None
点击查看代码
class APIView(View):
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES

    def perform_authentication(self, request):
        # Request()中的user
        request.user

    def initial(self, request, *args, **kwargs):
        self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)

    def get_authenticators(self):
       # 优先读取UserView()中的authentication_classes,没有则读取APIView()中的, 
       # 并返回实例化对象
        return [auth() for auth in self.authentication_classes]
    
    def initialize_request(self, request, *args, **kwargs):
        return Request(
            request,
            parsers=self.get_parsers(),
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )

    def dispatch(self, request, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        # django中的request和认证组件 放入initialize_request()中封装 
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
           # drf的request放入self.initial()中封装
            self.initial(request, *args, **kwargs)
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
点击查看代码
class UserView(APIView):
    authentication_classes = [类1, 类2, 类3]

    def get(self, request):
        print(request.user, request.auth)
        return Response('UserView')

#  请求到来时
#  obj = UserView()
#  obj.dispatch()
#  类UserView()中,没有dispatch()方法,到父类APIView()中找
点击查看代码
class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token = request.query_params.get('token')
        if token:
            return'zyb', token
        raise AuthenticationFailed({'code': 200, 'error': '认证失败'})
posted @ 2024-03-08 10:43  周亚彪  阅读(14)  评论(0)    收藏  举报