使用Nginx进行SSL重定向

17

我在同一主机上有 http:// 和 https://,如下所示:

server {

    listen   80;
    listen   443 ssl;

    ...
    ...
}

我需要做的是将访问我的商店的用户重定向到https://。问题在于我有很多语言:

  • https://example.com/en/shop
  • https://example.com/fr/shop
  • 等等...

我尝试过这个方法,但它没有起作用(nginx:配置文件/etc/nginx/nginx.conf测试失败)

if ($server_port = 80) {
    location (en|fr)/shop {
        rewrite ^ https://$host$request_uri permanent;
    }
}
5个回答

47

如果涉及到重定向,最好使用301重定向而不是使用if语句(请参见http://wiki.nginx.org/Pitfalls上的服务器名称)。我创建了一个gist,其中包含配置了SSL、Rails和Unicorn的nginx.conf

https://gist.github.com/Austio/6399964

这里将是与您相关的部分。

server {
    listen      80;
    server_name example.com;
    return 301  https://$host$request_uri;
}

(抱歉挖出了一个旧帖子)为了避免不良实践,我认为这应该被标记为答案。 - Ha-Duong Nguyen
7
不使用硬编码的域名,可以这样写:返回 301 https://$host$request_uri; - Nam Nguyen

11

或者更好的方法是避免硬编码服务器名称

server {
  listen 80;
  rewrite (.*) https://$http_host$1 permanent;
}

6
为了在匹配location时使用正则表达式,需要在表达式前加上~~*
if ($server_port = 80) {
    location ~ (en|fr)/shop {
        rewrite ^ https://$host$request_uri permanent;
    }
}

根据文档

使用正则表达式时,必须使用前缀:

  1. "~" 表示区分大小写的匹配
  2. "~*" 表示不区分大小写的匹配

由于nginx不允许在if块内嵌套location块,请尝试以下配置:

if ($server_port = 80) {
    rewrite ^/(en|fr)/shop https://$host$request_uri permanent;
}

我在你的代码中又遇到了一个错误:重新启动nginx:nginx:[emerg]“location”指令不允许在此处。 - Adam
2
@AdamSilver:你不能在if块内使用location(请参阅location的文档)。只需更改重写规则,仅在路径以(en|fr)/shop开头时进行重写。 - user142162
但我会得到一个重定向循环! - Adam
@AdamSilver:你不应该这样做。你保留你的“if”,但只在其中嵌套一个“rewrite”。 - user142162

2

最好能够避免if语句,同时保留尾部路径:

server {
  listen 80;
  server_name example.com;
  rewrite (.*) https://example.com$1 permanent;
}

permanent 负责处理301。


2

另一种使用 error_page 497 的方法

server {
    listen 80;
    listen 443;

    ssl on;
    error_page 497  https://$host$request_uri;
    ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接