我想强制使用 HTTPS 和顶级域名(例如https://example.com) 在我的应用程序中通过使用位置块的 nginx 配置。我目前有以下 nginx_app.conf 文件(它适用于 apex 和 www 子域,以及 http 和 https):
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
}
为了强制使用 apex 域和 https,我尝试使用以下 if 语句,检查 $scheme 和 $host 变量,但出现页面未正确重定向的错误。我还添加了 HSTS 指令。
location / {
if ($scheme = http) {
rewrite ^/(.*) https://$host/$1 permanent;
}
if ($host = www.example.com) {
rewrite ^/(.*) https://example.com/$1 permanent;
}
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
add_header Strict-Transport-Security "max-age=86400";
}
使用 nginx 配置强制 http 和 apex 域的正确方法是什么?顺便说一句,我正在使用 heroku (带有 DNSimple) 来部署我的应用程序,因此我希望以下两个域都能正常工作:https://example.herokuapp.com和https://example.com。
更新:我尝试将 if 语句从位置块移到默认服务器块(点击此处),并将返回的重写更改为如下,但仍然不起作用。在请求 http 时,我仍然收到“页面未正确重定向”的错误,在请求 www 子域时,仍然收到“无法连接错误”的错误。
if ($scheme = http) {
return 301 https://$host$request_uri;
}
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
}
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|config)\.php(/|$) {
# fastcgi_pass directives go here...
add_header Strict-Transport-Security "max-age=86400";
}
答案1
1)这里的问题可能是 Heroku 负载均衡器。当访问请求进入您的应用程序时,请求又是 HTTP。这只是内部路由。您无法针对进行测试$scheme
。但 Heroku$http_x_forwarded_proto
在这些请求上设置了一个标头。
if ($http_x_forwarded_proto != "https") {
return 301 https://$host$request_uri;
}
来源:https://discussion.heroku.com/t/force-ssl-and-no-www-with-nginx-configuration/856
2a)要定向到 no-www,您可以使用以下命令:
server {
listen <%= ENV["PORT"] %>;
server_name "~^www\.(.*)$";
return 301 https://$1$request_uri;
}
为了测试,您应该使用 302 而不是 301,因为浏览器将缓存 301 重定向。
这个也会将您重定向到 https。但仅限于 www 子域,因此您必须保留上述$http_x_forwarded_proto
重定向。
2b)另一种选择是使用带有 www 子域的服务器块并将其重定向到非 www 域,如下所示:
server {
listen <%= ENV["PORT"] %>;
server_name www.example.com;
location / {
return 301 https://example.com$request_uri;
}
}
server {
listen <%= ENV["PORT"] %>;
server_name example.com;
location / {
try_files $uri $uri/ /index.html =404;
}
}
代码<%= ENV["PORT"] %>
来自构建包。在 Heroku 上您无法监听端口 80。
答案2
最好的方法是进行 301 重定向。
server {
listen 80;
return 301 https://$host$request_uri;
}