Custom Permission Mixin Django Rest Framework

Я пытаюсь создать пользовательский mixim, который обрабатывает дополнительные проверки разрешений в моих представлениях.

Вот что я пробовал:

    class ProfilePermissionsRequiredMixin:
    required_permissions = []

    def get_required_permissions(self):
        return self.required_permissions

    def dispatch(self, request, *args, **kwargs):
        # Check if the user is authenticated
        if not request.user.is_authenticated:
            raise PermissionDenied("You must be logged in to access this resource.")

        # Get the user's profile
        profile = request.user.profile

        # Check if the profile has all the required permissions
        if all(profile.has_perm(perm) for perm in self.get_required_permissions()):
            return super().dispatch(request, *args, **kwargs)

        # Return 403 Forbidden if any permission check fails
        raise PermissionDenied("You do not have permission to access this resource.")

Проблема в том, что запрос, который я получаю, не аутентифицирован. Я использую пользовательский класс аутентификации, и он, очевидно, не применяется в деспетчере.

Что я могу сделать, чтобы исправить это?

В методе диспетчеризации drf APIView есть две части, связанные с аутентификацией.

    def dispatch(self, request, *args, **kwargs):
        ...
        self.args = args
        self.kwargs = kwargs
        -----------------------------------------------------------
        request = self.initialize_request(request, *args, **kwargs)
        -----------------------------------------------------------
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            --------------------------------------
            self.initial(request, *args, **kwargs)
            --------------------------------------   
            # Get the appropriate handler method
            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

Сначала вызывается метод initialize_request, в котором импортируются и создаются классы аутентификации, установленные в View.

Ниже приводится вызов метода initial, который вызывает метод perform_authentication, метод, выполняющий практический процесс аутентификации.

  def dispatch(self, request, *args, **kwargs):
        # Check if the user is authenticated
        if not request.user.is_authenticated:
            raise PermissionDenied("You must be logged in to access this resource.")

        # Get the user's profile
        profile = request.user.profile

        # Check if the profile has all the required permissions
        if all(profile.has_perm(perm) for perm in self.get_required_permissions()):
            return super().dispatch(request, *args, **kwargs)

        # Return 403 Forbidden if any permission check fails
        raise PermissionDenied("You do not have permission to access this resource.")

В вашем методе dispatch часть, в которой происходит процесс аутентификации, предположительно будет super(). dispatch().

Поэтому я думаю сначала вызвать super().dispatch(), сохранить результаты и вернуть ошибку, если проверка require_permission не удалась.

      def dispatch(self, request, *args, **kwargs):
        response = super().dispatch(request, *args, **kwargs)
        # Check if the user is authenticated
        if not request.user.is_authenticated:
            raise PermissionDenied("You must be logged in to access this resource.")

        # Get the user's profile
        profile = request.user.profile

        # Check if the profile has all the required permissions
        if all(profile.has_perm(perm) for perm in self.get_required_permissions()):
            return response

        # Return 403 Forbidden if any permission check fails
        raise PermissionDenied("You do not have permission to access this resource.")
Вернуться на верх