Отсутствует пользовательский заголовок в django, nginx и gunicorn

#django #configuration #http-headers #nginx #gunicorn

#django #конфигурация #http-заголовки #nginx #gunicorn

Вопрос:

Отказ от ответственности:

Я работаю в проекте, где существует «огромное» веб-приложение, у которого есть API для мобильных телефонов, поэтому изменить API не вариант.

Это приложение было разработано давно, и над ним работали несколько разработчиков,

Сказав это, проблема заключается в следующем;

В API для мобильных устройств этого сайта (просто просматривает, а не возвращает данные json) код ищет токен, но делает это в заголовках запроса:

 token = request.META.get('HTTP_TOKEN')
  

Когда я тестирую этот API локально, работает нормально, но в рабочей среде нет, поэтому я пытаюсь выяснить, что происходит, и нашел это:

django преобразует заголовки, даже пользовательские заголовки, в ключи в запросе.МЕТА, я использую urllib2 и запросы для тестирования api, и проблема в производстве заключается в том, что на рабочем сервере запрос.У META никогда не было ключа с именем HTTP_TOKEN, поэтому, выполнив небольшую отладку, я серьезно думаю, что проблема заключается в том, как мы обслуживаем приложение django.

Мы используем django1.3, nginx, gunicorn, virtualenvwrapper, python2.7.

Мой главный подозреваемый — nginx, я думаю, каким-то образом nginx получает заголовок, но не пересылает его в django, я пытаюсь провести некоторое исследование по этому поводу, но я нашел только информацию о заголовках безопасности и пользовательских заголовках из nginx, но я не нахожу документ или что-то о том, как сообщить nginx, что этот заголовок разрешен, и не удалять его.

Мне нужна помощь здесь, первое, что нужно проверить, получает ли nginx заголовок, но я просто немного знаю о nginx, и я не знаю, как указать ему регистрировать заголовки запросов.

Спасибо

Обновить

файл nginx conf

Комментарии:

1. Можете ли вы доказать это предположение? Зарегистрируйте запрос как от nginx, так и от django и убедитесь, что в заголовках HTTP действительно есть разница.

2. Частично это проблема, при тестировании скрипта с использованием urllib2 и запросов я определяю заголовки, которые я отправляю, в представлении я печатаю заголовки, которые я получаю, на сервере разработки заголовки в порядке, но на производстве django не получает заголовок HTTP_TOKEN.

3. При этом я ищу способ указать заголовки запросов на печать nginx, но документ немного ужасен

4. Заголовок запроса буквально HTTP_TOKEN? Или просто токен?

5. ТОКЕН, но django добавляет HTTP_

Ответ №1:

Если доступ к Django осуществляется с помощью uwsgi_pass, то в соответствующих расположениях …

 # All request headers should be passed on by default     
# Make sure "Token" response header is passed to user 
uwsgi_pass_header  Token;
  

Если доступ к Django осуществляется с помощью fastcgi_pass, то в соответствующих расположениях …

 # All request headers should be passed on by default     
# Make sure "Token" response header is passed to user 
fastcgi_pass_header  Token;
  

Если доступ к Django осуществляется с помощью proxy_pass, то в соответствующих расположениях …

 # All request headers should be passed on by default
# but we can make sure "Token" request header is passed to Django 
proxy_set_header Token $http_token;

# Make sure "Token" response header is passed to user 
proxy_pass_header  Token;
  

Это должно помочь исключить вероятность того, что Nginx не передает информацию из вашей проблемы.

Комментарии:

1. Предполагая, что вы имели в виду «gunicorn или …», тогда ответ заключается в том, что это директивы nginx. повсеместно они дали вам несколько ссылок ранее.

2. Интересно отметить, что у меня лично были проблемы с передачей заголовков, имя которых содержит символы подчеркивания при использовании uwsgi_pass_header. Например, заголовок AUTH_TOKEN никогда не достигнет Django, но при использовании AUTHTOKEN это произойдет!

Ответ №2:

В вашем файле конфигурации nginx (например, mysite_nginx.conf) в разделе server добавьте этот параметр: uwsgi_pass_request_headers on; .

Например:

 server {
    # the port your site will be served on
    listen      8000;

    ...

    underscores_in_headers on;
}
  

И если доступ к Django проходит через uwsgi_pass, вам нужно добавить этот параметр uwsgi_pass_request_headers on; в раздел location .

Например:

 location / {
    include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    uwsgi_pass_request_headers on;
    uwsgi_pass  django;
}
  

Ответ №3:

Я думаю, это то, что вам нужно:

 log_format combined '$remote_addr - $remote_user [$time_local]  '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" "$http_http_token" "$upstream_http_http_token"'
  

для регистрации происходящего.

Вы можете заглянуть глубже в раздел proxy_set_header в модуле восходящего прокси, чтобы узнать, как передавать нужные вам заголовки.

Вы можете найти документацию здесь:

Последняя запись, похоже, указывает на то, что nginx передает большинство заголовков по умолчанию

Ответ №4:

Я не нашел реального ответа, но смог найти обходной путь. У меня была такая же проблема со стандартными заголовками RFC, если они не совпадают и если изменены с тех пор, поэтому мое решение протестировано для этих заголовков.

Добавлено в мою конфигурацию nginx:

 uwsgi_param HTTP_IF_NONE_MATCH $http_if_none_match;
uwsgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since;
  

Я не могу объяснить, почему nginx отказывается передавать эти заголовки в uwsgi по умолчанию. Эта конфигурация вызывает его. Теперь страницы генерируют 304 по мере необходимости.

Для исходного вопроса о нестандартном заголовке «token» это должно сработать:

 uwsgi_param HTTP_TOKEN $http_token;
  

Ответ №5:

Приведенных выше ответов достаточно, чтобы мы могли найти способ. Но все еще есть досадный момент, который нам нужно знать. Да, это очень раздражает.

 proxy_set_header X_FORWARDED_FOR # oops it never works. 1.16.1 on centos7
proxy_set_header X-FORWARDED-FOR # this will do the job
  

Итак, вы поняли. Подчеркивание никогда не могло появиться в имени настраиваемой переменной. Вместо этого используйте дефис.

Возможно, Nginx в некоторых грамматических случаях используются символы подчеркивания. Кто-то указал, что официальная ссылка будет оценена.

Ответ №6:

Это зависит от того, как называется пользовательский заголовок. Мой был в формате «SomethingLike.this», он содержит точку. Не удалось переименовать заголовок в запросе, потому что это не наш код. Так что написание этого не сработало бы:

 proxy_set_header SomethingLike.this $http_somethinglike.this;
proxy_pass_header  SomethingLike.this;
  

Также это не сработало бы:

 underscores_in_headers on;
  

потому что мне понадобится dots_in_headers директива, которой не существует.

Но я обнаружил, что могу передать ВСЕ заголовки, просто добавив:

 ignore_invalid_headers off;
  

Передача всех заголовков может быть небезопасной, пожалуйста, используйте с осторожностью.