Настройки Django ALLOWED_HOSTS и CSRF_TRUSTED_ORIGINS не до конца понятны
Мой сервер Django работает на 127.0.0.1:8001. Я использую nginx для обратного проксирования моего сервера django на порт 80.
Конфиг nginx выглядит следующим образом:
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8001;
}
location /static {
root STATIC_ROOT;
}
}
Я запутался, когда пытался понять ALLOWED_HOSTS
и CSRF_TRUSTED_ORIGINS
настройки.
Все эти 2 настройки не работают:
ALLOWED_HOSTS = ["example.com"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
Или
ALLOWED_HOSTS = ["127.0.0.1"]
CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1"]
Только это работает
ALLOWED_HOSTS = ["127.0.0.1"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
Может ли кто-нибудь объяснить, почему я должен установить их по-другому?
Если возможно, то как вообще работает обратный прокси в nginx?
Когда ваш браузер отправляет запрос на сервер, он устанавливает несколько заголовков:
Host
, где указывается хост и номер порта сервера, на который отправляется запрос. MDN LinkOrigin
, которая указывает на источник (схема, имя хоста и порт), вызвавший запрос. Например, если агенту пользователя необходимо запросить ресурсы, включенные в страницу, или полученные скриптами, которые он выполняет, то происхождение страницы может быть включено в запрос. MDN Link
На первом этапе, когда вы открываете страницу по адресу https://example.com
и делаете HTTP-запрос, она отправляет следующие заголовки наряду с другими: Host: https://example.com
(что запрашивается) и Origin: https://example.com
(с какой страницы браузера отправляется запрос).
На втором этапе ваш запрос поступает в nginx. По умолчанию Nginx переписывает заголовок Host
на сам прокси-хост. Например, для
location / {
proxy_pass http://another.example.com:8080;
}
nginx устанавливает заголовок Host
на http://another.example.com:8080
.
Host
https://example.com
$proxy_host
proxy_pass
На третьем этапе Django получает запрос и проверяет заголовки Origin
и Host
. По умолчанию Django проверяет, что эти два заголовка равны. Если настроены какие-либо параметры, Django также принимает их во внимание.
Итак, подведем итоги:
После nginx у вас есть Host: http://127.0.0.1:8001
и Origin: https://example.com
В стандартном конфиге это не работает, потому что заголовки не совпадают.
ALLOWED_HOSTS = ["example.com"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
не работает, потому что Host - это http://127.0.0.1:8001
, а вы разрешаете только example.com
ALLOWED_HOSTS = ["127.0.0.1"]
CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1"]
не работает, потому что Origin - это https://example.com
, а вы разрешаете только http://127.0.0.1
ALLOWED_HOSTS = ["127.0.0.1"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
работает, потому что соответствует предоставленным заголовкам.