Django TokenAuthentication пропускает HTTP-заголовок "Авторизация" - программирование
Подтвердить что ты не робот

Django TokenAuthentication пропускает HTTP-заголовок "Авторизация"

Я пытаюсь использовать TokenAuthentication с одним из своих представлений. Как описано в http://django-rest-framework.org/api-guide/authentication.html, я добавляю токен, полученный мной из входа в качестве HTTP-заголовка, который называется "Авторизация" в отправляемом запросе.

Проблема заключается в том, что в моих unittests аутентификация терпит неудачу. Заглядывая в класс TokenAuthentication, я вижу, что проверяемый заголовок - это "HTTP_AUTHORIZATION", а не "Authorization"

Вид, который я использую:

class DeviceCreate(generics.CreateAPIView):
    model = Device
    serializer_class = DeviceSerializer

    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

Изменение заголовка в "HTTP_AUTHORIZATION", похоже, работает, но что-то не так.

Я что-то пропустил?

4b9b3361

Ответ 1

Заглядывая в класс TokenAuthentication, я вижу, что проверяемый заголовок является "HTTP_AUTHORIZATION", а не "Authorization"

Не совсем верно, когда вы выполняете поиск в запросе META dict, заголовки, которые он действительно ищет, не имеют предшествующего HTTP_, поэтому request.META.get('HTTP_AUTHORIZATION', '') фактически ищет заголовок Authorization в запросе.

Проблема заключается в том, что в моих unittests аутентификация терпит неудачу Изменение заголовка в "HTTP_AUTHORIZATION", похоже, работает

Я не дважды проверял, как выглядит тестовый клиент, но я считаю, что настройка HTTP_AUTHORIZATION - это то, что вам нужно сделать, чтобы получить эквивалент фактической установки заголовка Authorization. Если вы действительно сделали HTTP-запрос, вы должны найти, что настройка заголовка auth работает точно так, как вы ожидали.

См. документацию request.META здесь: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Edit

Django docs при поиске заголовков в request.META:

За исключением CONTENT_LENGTH и CONTENT_TYPE, как указано выше, любые HTTP-заголовки в запросе преобразуются в META-ключи посредством преобразование всех символов в верхний регистр, заменяя любые дефисы на подчеркивания и добавление префикса HTTP_ к имени. Так, например, заголовок, названный X-Bender, будет сопоставлен с ключом META HTTP_X_BENDER.

Django docs по настройке заголовков с тестовым клиентом:

Однако вы можете использовать аргументы ключевых слов, чтобы указать некоторые заголовки по умолчанию. Например, в каждом запросе будет отправлен заголовок User-Agent HTTP:

  

c = Клиент (HTTP_USER_AGENT = 'Mozilla/5.0')

  

Ответ 2

Ответ Tom в порядке, но не полный.

Ваш код может нормально работать в dev environmentnement (с runserver), но если вы попробуете его на WSGI-сервере (Apache в моем случае), сервер может лишить заголовок авторизации!

Вы можете найти на Boone Blog хорошее исправление для вашего Apache conf, чтобы сохранить заголовок авторизации в запросе и заставить его работать отлично:

RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]