使用 Nginx 位置配置重定向到 HTTPS 和 Apex 域

使用 Nginx 位置配置重定向到 HTTPS 和 Apex 域

我想强制使用 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.comhttps://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;
}

相关内容