重写重定向以包括用于访问服务的端口

Naf*_*Kay 5 redirect http nginx

我有这样的设置:

在此输入图像描述

使用我的Vagrant开发环境的用户localhost:8080在他们的主机上访问,该主机被转发到Vagrant到运行在localhost:80客户端的NGINX .有些请求被转发到我在客户机localhost:8080上运行的应用程序服务器,有些是NGINX提供的静态文件.

当我访问我的网站时,会发生奇怪的事情.我有一个登录页面,该页面在成功时重定向,并且URL被重写http://localhost:8080/loginhttp://localhost:80/login.

这是我网站的NGINX配置:

upstream appserver {
    server 127.0.0.1:8080;
}

upstream production {
    server www.mysite.com:443;
}

server {
    listen 80 default_server;
    server_name _;

    client_max_body_size 20M;

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

    index /index;

    location ~ ^(/js/testpage.js) {
        alias   /vagrant/artifacts/www/js/testpage.js;
    }

    location ~ ^(/test/js/app.js) {
        alias   /vagrant/test/js/app.js;
    }

    location ~ /test/js/app_router.js {
        alias   /vagrant/test/js/app_router.js;
    }

    location ~ /test/js/app_layout_controller.js {
        alias   /vagrant/test/js/app_layout_controller.js;
    }

    location ~ /test/js/apps/navbar/sections/layout/navbar_layout_controller.js {
        alias   /vagrant/test/js/apps/navbar/sections/layout/navbar_layout_controller.js;
    }

    location ~ /test/js/apps/navbar/sections/navbar/navbar_options_view.js {
        alias   /vagrant/test/js/apps/navbar/sections/navbar/navbar_options_view.js;
    }

    location ~ /test/js/apps/navbar/sections/navbar_all_views.js {
        alias   /vagrant/test/js/apps/navbar/sections/navbar_all_views.js;
    }

    location ~ ^/test/js/apps/(.*/testpage_.*\.js)$ {
        alias   /vagrant/test/js/apps/$1;
    }

    location ~ ^/test/js/(.*)$ {
        alias /vagrant/js/$1;
    }

    location ~ ^/build/js/(.*)$ {
        alias /vagrant/artifacts/www/js/$1;
    }

    location ~ ^/build/css/(.*)$ {
        alias /vagrant/artifacts/www/css/$1;
    }

    location ~ ^/(.*main.*)\.[@\-_\/\d\w]+\.(js|css)$ {
        alias /vagrant/$1.$2;
    }

    location ~ ^/(css|js|fonts|favicon.ico) {
        root   /vagrant;
    }

    location ~ ^/receipts/js/(.*)$ {
        alias /vagrant/receipts/js/$1;
    }

    location ~ ^/bower_components/(.*)$ {
        alias /vagrant/bower_components/$1;
    }

    location ~ ^/login-promo/ {
        access_log off;
        proxy_pass https://production;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ~ ^/(admin|login|logout|index|build|testpage|receipts|open|reset|resetpage|privacy|change|activeUser|personPrivacyAcceptances) {
        access_log off;

        proxy_pass http://appserver;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定重定向实际来自哪里,它可能来自应用服务器后端或来自前端JavaScript.有没有办法可以确保所有重定向都占用访问客户端使用的端口?


更新:只需添加<a href="/login">login</a>指向根页面的链接,并尝试使用该链接进行导航,将我重定向到http://localhost:80/login而不是http://localhost:8080/login.

Naf*_*Kay 0

这似乎是由于应用程序代码中的重定向错误造成的。

如果您具有与上述类似的体系结构并且遇到了问题,那么您遇到问题的原因很可能是由于在不考虑标头的情况下天真地尝试进行重定向Host

nginx 后面的应用程序会看到如下请求:

GET /path/to/resource
Host: virtualinstance:8888
Run Code Online (Sandbox Code Playgroud)

不幸的是,当它构造重定向时,它会做一些愚蠢的事情并重建重定向而不考虑标Host头,而是选择它知道正在使用的主机和端口。破坏我的重定向的代码看起来像这样:

return redirect("http://" + getHostName() + "/" + getPath())
Run Code Online (Sandbox Code Playgroud)

首先,它对协议进行硬编码是不好的,但更糟糕的是它使用一种获取主机名而不考虑端口的方法。这将返回重定向到http://localhost/path,而不是http://localhost:8888/path

开发人员,这就是为什么您应该始终使用Host标头作为重定向源的原因:

return redirect("%s://%s/%s" % (getProtocol(), getHeader("Host"), 
    getPath())
Run Code Online (Sandbox Code Playgroud)

Host这将使用原始协议、来自 的全文和路径进行合理的重定向。