【问题标题】:Multi-condition Nginx Redirect多条件 Nginx 重定向
【发布时间】:2016-02-12 17:55:42
【问题描述】:

在 nginx 中,我试图找出处理重定向的最佳方法,以强制所有非 https 流量到 https,当且仅当流量不在 /assets/* 路径中时。

用例:通过 AWS CloudFront 启用 javascript 和 css 缓存,而无需从服务器链接 SSL 证书。

这是我正在尝试的:

server {
    listen  80;

    if ( $http_x_forwarded_proto = "http" ) {
        set $redir please_redir;
    }

    location ~ ^/assets/|favicon.ico {
        set $redir  dont_redir;
        root /home/deploy/www/public;
        gzip_static on;
        expires max;
        add_header Cache-Control public;
    }


    if ( $redir = please_redir ) {
        return  301 https://$http_host$request_uri;
    }

    location / {
        proxy_pass http://127.0.0.1:9292/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

我也尝试将 'please_redir' 用引号括起来,但没有成功。有任何想法吗?欢迎其他可行的解决方案。请记住,它必须是非 https 请求并且不在 /assets/ 路径中。谢谢!

【问题讨论】:

    标签: ruby-on-rails nginx url-redirection amazon-cloudfront


    【解决方案1】:

    只需将您的主服务器设置为仅侦听 https,并在 http 上设置一个单独的服务器用于重定向和资产。

    额外的服务器配置可能看起来像

    server {
      server_name  example.com;
    
      location ~ ^/assets/|favicon.ico {
        root /home/deploy/www/public;
        gzip_static on;
        expires max;
        add_header Cache-Control public;
      }
    
      location / {
        rewrite ^(.*) https://example.com$1 permanent;
      }
    }
    

    【讨论】:

    • 这里的问题是,所有请求都在端口 80 上进入(ssl 在负载均衡器处卸载)。您可以在我的代码中看到我依赖于 http_x_forwarded_proto
    • 然后尝试在/位置内移动条件(并立即重写,不使用变量)
    【解决方案2】:

    使用 ^~ 和 = 位置以获得最佳性能。重复的静态内容指令是值得的。为了便于维护,您始终可以将它们放在包含的文件中:

    server {
        listen 80;
        root /home/deploy/www/public;
    
        location ^~ /assets/ {
            gzip_static on;
            expires max;
            add_header Cache-Control public;
        }
    
        location = /favicon.ico {
            gzip_static on;
            expires max;
            add_header Cache-Control public;
        }
    
        location / {
            return 301 https://$http_host$request_uri;
        }
    }
    

    【讨论】:

    • 谢谢你,它并没有完全回答这个问题,但它确实让我找到了解决方案。重定向位于错误的位置。
    【解决方案3】:

    问题在于重定向的位置。愚蠢的错误......对于任何希望通过 CloudFront 发送 rails 资产管道的人,您将在使用 CORS 的 woff 和 tiff 文件上遇到问题,并且您需要发送额外的标头以允许原始请求。我们选择通过 http 向 cloudfront 提供静态资产,以避免在 CloudFront 中链接 SSL 证书。这是解决方案。

    server {
        listen  80;
    
        location ~ ^/assets/|favicon.ico|robots.txt {
            root /home/deploy/www/public;
            gzip_static on;
            expires max;
            add_header Cache-Control public;
            if ($http_origin ~* 'https?://subdomain\.cloudfront.net') {
                    add_header 'Access-Control-Allow-Origin' "$http_origin";
                    add_header 'Access-Control-Allow-Credentials' 'true';
                    add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
                    add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With';
            }
        }
    
        location / {
    
            # ELB Injects:  X-Forwarded-Proto: HTTP or HTTPS
            if ( $http_x_forwarded_proto = "http" ) {
                return  301 https://$http_host$request_uri;
            }
    
            proxy_pass http://127.0.0.1:9292/;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      相关资源
      最近更新 更多