Как указать явное имя хоста в настройках Django? - PullRequest
0 голосов
/ 22 января 2020

Я работаю над проектом Django, который выполняется через несколько Docker контейнеров, а сам сайт Django является промежуточным ПО, к которому Nginx контейнер пересылает запросы. А для тестирования порт 80 контейнера Nginx сопоставлен с 8080. Таким образом, я go на http://localhost: 8080 / и вижу веб-сайт Django.

I У меня проблема с тем, что URL перенаправления (созданный из пакета social-auth-app-django для входа в Google) использует http://localhost в качестве базы, а не http://localhost:8080.

Настройка LOGIN_REDIRECT_URL не то, что я ищу, потому что она происходит после успешной аутентификации .

Я пытался SOCIAL_AUTH_LOGIN_REDIRECT_URL, что было где-то упоминается , но это было для старой версии и, похоже, больше ничего не делает.

Поскольку Django использует build_absolute_uri для всех абсолютных URL, должен быть способ переопределить базовый URL и / или хост?

1 Ответ

0 голосов
/ 23 января 2020

TL; DR = Nginx не имеет понятия портов, сопоставленных с Docker, и нуждается в их жестком кодировании.

Аналогичная проблема: https://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf

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

location / {
    proxy_pass http://web:7000;
    proxy_set_header Host $host:8080;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Обратите внимание на неудачное жесткое кодирование порта: $host:8080. «Внешняя» проблема заключается в том, что порт контейнера Nginx отображается с помощью Docker на 8080 (-p 80:8080), и поэтому не подозревает , что он фактически работает на порте 8080; Nginx определяет себя как работающий на порте 80.

Там имеет значение Django для SOCIAL_AUTH_LOGIN_REDIRECT_URL, но указывает его так:

SOCIAL_AUTH_LOGIN_REDIRECT_URL = 'http://localhost:8080/complete/google-oauth2/'

Причины это происходит при попытке аутентификации через Google:

AuthMissingParameter at / complete / google-oauth2 /

Отсутствует состояние необходимого параметра

Метод запроса: GET

URL запроса: http://localhost: 8080 / complete / google-oauth2 /

Django Версия: 2.1.5

Тип исключения: AuthMissingParameter

Значение исключения:

Отсутствует требуемое состояние параметра

Местоположение исключения: /usr/local/lib/python3.6/site-packages/ social_core / backends / oauth.py в validate_state, строка 88

Python Исполняемый файл: / usr / local / bin / python

Python Версия: 3.6.10

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

Django версия 2.1.5 код f или получающий хост:

def _get_raw_host(self):
    """
    Return the HTTP host using the environment or request headers. Skip
    allowed hosts protection, so may return an insecure host.
    """
    # We try three options, in order of decreasing preference.
    if settings.USE_X_FORWARDED_HOST and (
            'HTTP_X_FORWARDED_HOST' in self.META):
        host = self.META['HTTP_X_FORWARDED_HOST']
    elif 'HTTP_HOST' in self.META:
        host = self.META['HTTP_HOST']
    else:
        # Reconstruct the host using the algorithm from PEP 333.
        host = self.META['SERVER_NAME']
        server_port = self.get_port()
        if server_port != ('443' if self.is_secure() else '80'):
            host = '%s:%s' % (host, server_port)
    return host
...