我有这样的设置:
使用我的Vagrant开发环境的用户访问其主机上的localhost:8080
,然后将其转发到Vagrant,转发到运行于localhost:80
客户端的NGINX。有些请求会转发到我在客户端localhost:8080
运行的应用服务器,有些请求是NGINX提供的静态文件。
当我访问我的网站时,会发生奇怪的事情。我有一个登录页面,该页面在成功时重定向,并且URL从http://localhost:8080/login
重写为http://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;
}
}
我不确定重定向实际来自哪里,它可能来自应用服务器后端或来自前端JavaScript。有没有办法可以确保所有重定向都占用访问客户端使用的端口?
更新:只需在根页面添加<a href="/login">login</a>
链接,然后尝试使用该链接进行导航,即可将我重定向到http://localhost:80/login
而不是http://localhost:8080/login
。
答案 0 :(得分:1)
这可能是将客人的nginx端口发送到主机上的另一个端口的不良副作用。
请参阅http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
停用最后一个位置块中的代理重定向应该可以解决问题:
proxy_redirect off;
答案 1 :(得分:0)
由于port_in_redirect
默认为on
,可能会发生这种情况。请参阅:http://wiki.nginx.org/HttpCoreModule#port_in_redirect
禁用这可能会阻止一些混淆为什么端口被应用。
从那里开始,如果需要,在代理传递重定向中设置适当的host_port
或remote_port
就很简单了。通过查看您的配置,您似乎习惯使用核心模块变量,包含这些变量将非常简单。
请参阅:
http://wiki.nginx.org/HttpCoreModule#.24remote_port http://wiki.nginx.org/HttpCoreModule#.24server_port
答案 2 :(得分:0)
这似乎是由于应用程序代码中的重定向错误造成的。
如果您具有与上述类似的体系结构并且遇到问题,则可能是您遇到问题的原因是由于尝试重定向而没有考虑Host
标头。
你的nginx背后的应用程序会看到这样的请求:
GET /path/to/resource
Host: virtualinstance:8888
不幸的是,当它构造重定向时,它会做一些愚蠢的事情并重新构建重定向而不考虑Host
标头,而是选择它知道它正在使用的主机和端口。破坏我的重定向的代码看起来像这样:
return redirect("http://" + getHostName() + "/" + getPath())
首先,它很难对协议进行硬编码,但更糟糕的是,它使用的方法在不考虑端口的情况下获取主机名。这会返回重定向到http://localhost/path
,而不是http://localhost:8888/path
。
开发人员,这就是为什么您应该始终使用Host
标头作为重定向的来源:
return redirect("%s://%s/%s" % (getProtocol(), getHeader("Host"),
getPath())
这使用原始协议,Host
的全文和路径进行了理智的重定向。