Nginx перенаправляет на ```https://server_name/ ```URL вместо ```https://server_name/projectname/``` после изменения URL с http на https

Nginx перенаправляет на ```https://server_name/ ```URL вместо ```https://server_name/projectname/``` после изменения URL с http на https

У меня есть несколько URL-адресов, например https://server_name/projectname/, теперь проблема в том, что если я ввожу этот URL-адрес в браузере, Django (или Nginx) перенаправляет меня на https://server_name/, которого не существует. На самом деле, он должен перенаправлять меня на https://server_name/projectname/. Теперь вопрос в том, как я могу сказать Django (или Nginx ) сделать это, я не знаю, в Django или в конфигурации Nginx. Я пробовал FORCE_SCRIPT_NAME= '/projectname' в settings.py, но это не помогло для всех URL-адресов, например https://server_name/projectname/admin. Кстати, это работало очень хорошо до изменения HTTP на HTTPs.

Конфигурация Nginx в sites-available/project_name


upstream project_name_app{
  server unix:/home/webapps/project_name/run/gunicorn.sock fail_timeout=0;
}


server {

    listen 127.0.0.1:100;
    server_name servername;
    fastcgi_read_timeout 1600;

    proxy_connect_timeout       1600;
    proxy_send_timeout          1600;
    proxy_read_timeout          1600;
    send_timeout                1600;
    client_max_body_size 4G;

    access_log /home/webapps/projectname/logs/nginx-access.log;
    error_log /home/webapps/projectname/logs/nginx-error.log;

    location /static/ {
        alias   /home/webapps/projectname/project_name/static/;
    }

    location /media/ {
        alias   /home/webapps/projectname/project_name/media/;
    }

    location /{
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://project_name_app;
            break;

        }
    }

    # Error pages
    error_page 500 502 503 504 /500.html;
    location = /404.html {
        root /home/webapps/projectname/project_name/templates/;
    }
}

Конфигурация обратного прокси-сервера Nginx:

server {
        listen 80;
        server_name servername;

        # https redirect
        return 301 https://$host$request_uri;
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        ssl on;
        ssl_certificate ...;
        ssl_certificate_key ...;

        root /home/webapps/landing/landing;
        index index.html;

        # Improve HTTPS performance with session resumption
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        # Enable server-side protection against BEAST attacks
        ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "ddfdf";

        # RFC-7919 recommended: https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe4096
        ssl_dhparam /;
        ssl_ecdh_curve /;

        
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
        # add_header X-Frame-Options DENY always;
        add_header X-Frame-Options SAMEORIGIN;

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
        add_header X-Content-Type-Options nosniff always;

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
        add_header X-Xss-Protection "1; mode=block" always;

        # Reverse Proxy
        include /etc/nginx/sites-available/reverse-proxy.conf;
}




И включил обратный прокси в последней строке:


location /projectname/ {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_set_header Accept-Encoding "";

        proxy_read_timeout 1000;
        proxy_connect_timeout 1000;
        proxy_send_timeout 1000;

        proxy_pass http://localhost:100/;
        sub_filter '="/' '="/projectname/';

        sub_filter_once off;
}


Основной URL в Django


urlpatterns = [
    path('', include('pages.urls')),
    path('dashboards/', include('dashboards.urls')),
    path('django_plotly_dash/', include('django_plotly_dash.urls')),
    re_path('admin/', admin.site.urls),
    
]

URL-адрес страницы

urlpatterns = [
    path('', views.index, name='index-pages'),
    re_path(r'^login/$', views.login_page, name='login'),
    re_path(r'^logout/$', views.logout_user, name='logout'),
]

URL-адрес панели управления

urlpatterns = [
    path('dashboard/', views.dashboard, name='dashboard'),
 ]

решение1

Django отлично поддерживает SCRIPT_NAME. Независимо от того, принудительно ли он настроен в конфигурации, отправлен сервером WSGI или передан через любой обратный прокси, он будет работать сам по себе. Прыжки через обручи только для того, чтобы скрыть префикс пути от приложения, нужны или желательны только при работе с программным обеспечениемнетподдержка нахождения в корневой папке.

Настройте MEDIA_URL& STATIC_URLи удалите строки sub_filter/ sub_filter_onceи завершающий слеш proxy_passиз вашей конфигурации nginx. Этоотправить путьвключаяпрефикспередайте это gunicorn, и Django справится с этим.


Я бы также настоятельно рекомендовал исключить двойной прокси. Конфигурация, касающаяся приложения, может быть встроена прямо в location /projectname/ {}имя в блоке https-сервера, вместо того, чтобы устанавливатьдругойпотенциальный источник трудно диагностируемых особенностей/ошибок/уязвимостей HTTP-проксирования.

Связанный контент