我有一个奇怪的问题,尾随 /
我正在使用 nginx,它运行正常,只有一处小异常。
我有以下站点配置
server {
listen 80;
return 301 https://$server_name$request_uri/;
server_name sub1.sub2.domain.com;
}
server {
listen 443 ssl; # The ssl directive tells NGINX to decrypt
# the traffic
server_name sub1.sub2.domain.com;
ssl_certificate /etc/nginx/ssl/sub1.sub2.domain.com/server.crt; # This is the certificate file
ssl_certificate_key /etc/nginx/ssl/sub1.sub2.domain.com/server.key; # This is the private key file
location / {
proxy_pass http://1.1.1.1:8880;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
我有一个正在运行的异地身份验证服务,它保护着一个名为 secure 的子文件夹,因此如果请求 /secure 或 /secure/,它们将被发送到异地身份验证服务。一旦它们通过身份验证,它们将被重定向回它们最初请求的任何 URL。如果在身份验证后它们恰好请求 /secure/,则一切都会正常进行。如果它们输入 /secure(没有尾随 /),nginx 会在身份验证后执行 301 重定向,并将 https 替换为 http,这样它们就可以http://sub1.sub2.domain.com/secure然后通过另一个重定向回到 https
从我在这里读到的内容来看http://nginx.org/en/docs/http/ngx_http_core_module.html#location这是正确的行为,但将 /secure/ 和 /secure 定义为单独位置文件的解决方案似乎不起作用,并且该示例中也没有提到有关 https 到 http 更改的任何内容。任何帮助都将不胜感激。
答案1
您的应用程序对此负责,这是因为您需要使用额外的标头转发当前方案,例如,X-Forwarded-Proto
因为您禁用了它proxy_redirect
,这意味着重定向从上游服务器保持完整并直接发送给访问者,而无需 nginx 使其与位置上下文或当前服务器块中使用的方案相关。
因此请在那里修复它或者改用 nginx 的proxy_redirect
相关方法。
答案2
您在重定向中明确添加了尾部斜杠:
return 301 https://$server_name$request_uri/;
这显然不是你想要的。
因此不要添加尾部斜杠:
return 301 https://$server_name$request_uri;
答案3
所以事实证明文档是正确的(谁知道呢),我在尝试解决尾随 / 的第一个问题时引入了更多问题
我能够通过进行以下更改来解决该问题。
return 301 https://$server_name$request_uri;
(删除 http 重定向末尾的 /)
location = /secure {
return 301 https://$server_name$request_uri/;
}
对于在进入身份验证服务之前未在 secure 末尾放置 / 的任何人,这将执行重定向。
proxy_redirect http:// $scheme://;
这会将应用程序中的每个 http 重定向重写为 https