Настройки 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 Link
  • Origin, которая указывает на источник (схема, имя хоста и порт), вызвавший запрос. Например, если агенту пользователя необходимо запросить ресурсы, включенные в страницу, или полученные скриптами, которые он выполняет, то происхождение страницы может быть включено в запрос. 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"]

работает, потому что соответствует предоставленным заголовкам.

Вернуться на верх