Как использовать приложение Django Nginx с HTTP и HTTPS запросами?

У меня есть веб-приложение, которое использует Django в качестве бэкенда и Nginx вместе с Gunicorn в качестве обратного прокси. Я уже настроил конфигурацию Nginx, и она отлично работает, когда запросы отправляются по HTTPS. Но при HTTP-запросах происходит сбой.

Я хочу, чтобы приложение работало для HTTP и HTTPS запросов.

Некоторые из моих представлений Django содержат внутренние запросы, которые выполняются по HTTP, так как они должны быть совместимы с сервером разработки и производственным сервером

class LoginView(APIView):
   ...
        http_host = request.META["HTTP_HOST"]
        url = f"http://{http_host}/o/token/"
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        data = {
            'username': req_data['username'],
            'password': req_data['password'],
        }

        response = requests.post(url, headers=headers, data=data)
   ...

Моя конфигурация nginx следующая

server {
    listen 8000 ssl;

    server_name backend.test.com www.backend.test.com;

    access_log /var/log/nginx/app_backend.access.log;
    error_log /var/log/nginx/app_backend.error.log;

    location = /favicon.ico { access_log off; log_not_found off; }
    
    location /static/ {
        root /home/testuser/app_backend/app_backend;
    }
    
    location /media/ {
        root /home/testuser/app_backend/app_backend;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/testuser/app_backend/app_backend/app_backend.sock;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/backend.test.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/backend.test.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Я разместил VPS на digital ocean.

Как заставить сервер работать и для http-запросов, которые выполняются внутренними представлениями бэкенда

Примечание: Я пытался перенаправить все HTTP запросы на HTTPS только на производстве в Nginx, сделав это return 301 https://$host$request_uri;, но это не сработало

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

url = f"{request.scheme}://{request.META['HTTP_HOST']}/o/token"

примечание... что я не уверен на 100%, что это не сохранит порт (если это необходимо, это должно быть в META['SERVER_PORT'])

в качестве альтернативы определите второй HTTP-сервер (убедитесь, что вы удалили :8000 из первого сервера)

server {
    listen 8000 80; 

    server_name backend.test.com www.backend.test.com;

    access_log /var/log/nginx/app_backend.access.log;
    error_log /var/log/nginx/app_backend.error.log;

    location = /favicon.ico { access_log off; log_not_found off; }
    
    location /static/ {
        root /home/testuser/app_backend/app_backend;
    }
    
    location /media/ {
        root /home/testuser/app_backend/app_backend;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/testuser/app_backend/app_backend/app_backend.sock;
    }
}

но я думаю, что это в целом считается плохой практикой

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