Nginx:在一条路径上强制使用 SSL,在其他路径上强制使用非 SSL

pbr*_*ach 27 ssl nginx

如何设置 Nginx conf 文件以仅在我的站点中的一个路径上强制使用 SSL,而在所有其他路径上强制使用非 SSL?

例如,我希望 /user 下的所有 URL 都是 https,但所有其余的 URL 都是 http。

对于第一部分,我有:

rewrite ^/user(.*) https://$http_host$request_uri?;
Run Code Online (Sandbox Code Playgroud)

我不想使用“如果”。我认为它会利用操作顺序,但我不想以循环结束。

gru*_*ech 39

在您的 nginx 配置中,您应该有两个“服务器”区域。一种用于端口 80,一种用于端口 443(非 SSL 和 SSL)。只需在您的非 SSL 网站中添加一个位置即可重定向到您的 SSL 页面。

server {
    root /var/www/
    location / {
    }
    location /user {
        rewrite ^ https://$host$request_uri? permanent;
    }
}
Run Code Online (Sandbox Code Playgroud)

它会将所有以 /user 结尾的流量转发到您的 https:// 服务器。

然后,在您的 443 服务器中,您执行相反的操作。

server {
    listen 443;
    root /var/www/
    location / {
        rewrite ^ http://$host$request_uri? permanent;
    }
    location /user {
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法很好,但它属于几个常见的 [陷阱](http://wiki.nginx.org/Pitfalls),特别是“定位块内的根”和“税收重写” (2认同)

Hna*_*att 13

Nginx 允许在同server一块内处理 HTTP 和 HTTPS 。因此,您不必为两者重复指令,并且可以重定向您想要保护的路径

server {
  listen 80 default_server;
  listen 443 ssl;
  ... ssl certificate and other configs ...

  location /user {
    if ($scheme = 'http') {
      rewrite ^ https://$http_host$request_uri? permanent;
    }
  }

  ... your basic configuration ...
}
Run Code Online (Sandbox Code Playgroud)

一定不要ssl on那里放行,因为它会破坏普通的 HTTP。

或者,您可以以相同的方式将所有其他请求从 HTTPS 重定向回 HTTP:

if ($scheme = 'https') {
  rewrite ^ http://$http_host$request_uri? permanent;
}
Run Code Online (Sandbox Code Playgroud)

更新:正如 Alexey Ten 在评论部分友好指出的那样,检查scheme每个请求并不是一个好主意。您应该遵循配置 nginx 的声明方式。在这种情况下,通过重定向声明两个服务器块location,将公共逻辑移动到一个单独的文件,include并在两者中。所以 GruffTech 的回答更好。

  • 为每个请求都制定 nginx 检查方案是无效的。 (2认同)
  • 对常用指令使用 `include` 指令。一些重复是可以的。 (2认同)