У меня Nginx настроен как обратный прокси для приложения uWSGI (приложение Django). Из-за характера контента, который размещает приложение Django, иногда URL-адреса становятся длинными. Действительно долго. Из-за этого Referer
Заголовок HTTP также иногда может быть длинным.
Вот в чем проблема. Nginx отбрасывает Referer
получено от клиента, если оно превышает 1128 байт (обнаружено методом проб и ошибок). Все, что составляет 1128 байт или меньше, передается вышестоящему серверу. Все, что больше, падает. Это проблема, потому что механизм защиты Django CSRF требует неповрежденного Referer
.
Вот соответствующий раздел моей конфигурации Nginx. файл:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Я просмотрел документацию Nginx и не смог найти настройку, которая контролировала бы максимальную длину заголовков клиентов. Разочарованный, я даже начал переливать исходный код для Nginx, который тоже не дал ничего полезного.
Что мне нужно сделать, чтобы Nginx прошел Referer
без изменений для вышестоящего сервера?
Ответ Ксавьера и последующее обсуждение привело меня к настоящей причине этой проблемы: uWSGI. Похоже, что uWSGI удалял заголовок:
[WARNING] unable to add HTTP_REFERER
Решение было до боли простым - при запуске uWSGI мне нужно было просто включить следующую опцию:
--buffer-size 8192
Теперь все заголовки проходят в Django, и проверка CSRF проходит успешно.
Размер чтения заголовка Nginx контролируется двумя директивами:
client_header_buffer_size [buffer_size]
это буфер по умолчанию, который подходит в большинстве случаев
large_client_header_buffers [count] [buffer_size]
которые являются дополнительными буферами, выделяемыми по запросу, если они не помещаются в client_header_buffer_size
буфер. Вы должны адаптировать эту последнюю директиву к вашему случаю и убедиться, что buffer_size
больше, чем любая строка, переданная в запросе (заголовки + URL с методом HTTP и версией HTTP).