Подтвердить что ты не робот

Почему Django REST Framework предоставляет различные механизмы аутентификации

Почему Django REST Framework реализует другой механизм аутентификации, чем встроенный механизм Django?

Для этого есть два класса настроек, которые можно настроить:

  • settings.AUTHENTICATION_BACKENDS, который обрабатывает аутентификацию на уровне Django и
  • settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'], который аутентифицируется на уровне REST-Framework

Проблема, с которой я столкнулся, заключается в том, что у меня есть Middleware-уровень, который проверяет, вошел ли пользователь в систему или нет.

При использовании веб-клиента, который аутентифицируется через сеансы, это работает отлично. Тем не менее, с мобильного телефона или при запуске набора тестов (например, аутентификации с использованием заголовков HTTP и токенов) промежуточное ПО обнаруживает пользователя как AnonymousUser, но к моменту перехода на уровень REST Framework заголовок HTTP Authorization читать, и пользователь вошел в систему.

Почему они не оба происходят до промежуточного ПО? Кроме того, почему методы проверки подлинности REST Framework не полагаются на бэкэнд аутентификации Django?

4b9b3361

Ответ 1

Django Rest Framework по умолчанию не выполняет проверку подлинности в промежуточном программном обеспечении по той же причине, что и Django по умолчанию не выполняет проверку подлинности в промежуточном программном обеспечении: промежуточное программное обеспечение применяется ко всем представлениям и является чрезмерным, когда вы только хотите аутентифицировать доступ к небольшой части ваши взгляды. Кроме того, возможность предоставления различных методов аутентификации для разных конечных точек API является очень удобной функцией.

Методы проверки подлинности Rest Framework не полагаются на бэкэнд аутентификации Django, поскольку бэкэнд Django оптимизирован для общего случая и связан с пользовательской моделью. Rest Framework стремится облегчить:

  • Использовать множество методов аутентификации. (Вы хотите, чтобы аутентификация на основе HMAC выполнялась! Это невозможно с django auth framework)
  • Предоставлять данные API, не требуя при этом базы данных. (У вас есть база данных redis со всеми вашими данными в памяти? Подавайте ее в миллисекундах, не ожидая в оба конца совместной работы с моделью пользователя DB.)

Ответ 2

Ответ томаса хорошо объясняет причину. Мой ответ больше касается того, что вы можете с этим поделать. У меня также есть класс промежуточного программного обеспечения, который определяет текущего пользователя. Мне это нужно, потому что у нас есть некоторые автоматические процессы (cron), и я хочу приписать их суперпользователю, и у меня есть некоторые функции модели, которые не имеют доступа к объекту запроса, но должны знать, кто является текущим пользователем для различных функции. Так что это создало некоторые проблемы, как вы заметили, когда мы добавили API через среду REST. Вот мое решение (ваше должно быть адаптировано к вашему варианту использования):

from threading import local

_user = local()     # thread-safe storage for current user used by middleware below

class CurrentUserMiddleware(object):
    """ Defines Middleware for storing the currently active user """

    def process_request(self, request):
        if not request:
            # Clear the current user if also clearing the request.
            _user.value = 1  # One represents automatic actions done by super admin

        else:
            _user.value = request.user

            if not _user.value or not _user.value.is_authenticated:
                try:
                    authenticator = TokenAuthentication()
                    auth = authenticator.authenticate(request)

                    if auth:
                        _user.value = auth[0]
                except Exception as e:
                    pass

    def process_response(self, request, response):
        _user.value = None

        return response

Бит аутентификатора определяет, был ли запрос аутентифицирован REST Framework, и получает пользователя.