Ответ
Когда Django-приложение работает за обратным прокси-сервером (например, Nginx), информация о реальном клиенте (IP-адрес, протокол) передается через HTTP-заголовки. Для корректной обработки этих данных необходимо настроить Django.
Ключевые заголовки:
X-Forwarded-For: Содержит исходный IP-адрес клиента.X-Forwarded-Proto: Содержит исходный протокол (httpилиhttpsси).X-Forwarded-Host: Содержит исходное имя хоста, запрошенное клиентом.
Настройка в settings.py:
Чтобы Django доверял этим заголовкам и использовал их для обновления объекта request, необходимо установить следующие параметры:
# settings.py
# Доверяем заголовку X-Forwarded-Proto, который устанавливает прокси-сервер
# Это необходимо, чтобы request.is_secure() возвращал True для HTTPS-запросов
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Доверяем заголовку X-Forwarded-Host
USE_X_FORWARDED_HOST = True
# Обязательно добавьте доменное имя или IP-адрес вашего прокси в ALLOWED_HOSTS
ALLOWED_HOSTS = ['your-domain.com', 'localhost', '127.0.0.1']
Пример конфигурации Nginx:
Прокси-сервер должен быть настроен для передачи этих заголовков.
location / {
# Передаем запрос на Gunicorn/uWSGI
proxy_pass http://unix:/run/gunicorn.sock;
# Устанавливаем заголовки, которые будет использовать Django
proxy_set_header Host $host;
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;
}
После этой настройки request.META['REMOTE_ADDR'] будет содержать реальный IP-адрес клиента, а request.is_secure() будет корректно работать для HTTPS-соединений.