【问题标题】:How to preserve request url with nginx proxy_pass如何使用 nginx proxy_pass 保留请求 url
【发布时间】:2011-08-15 14:18:55
【问题描述】:

我在尝试使用 Thin 应用服务器时遇到了一个问题。

当 nginx proxies 使用 proxy_pass http://my_app_upstream; 对 Thin(或 Unicorn)的请求时,应用程序会收到 nginx 发送的修改后的 URL(http://my_app_upstream)。

我想要的是传递原始 URL 和来自客户端的原始请求而不进行任何修改,因为应用程序严重依赖它。

nginx'doc 说:

如果需要在 未处理的表格 then 指令 proxy_pass 应该在没有 URI 的情况下使用 部分。

但我不明白如何准确配置它,因为相关示例实际上使用的是 URI:

location  /some/path/ {
  proxy_pass   http://127.0.0.1;
}

那么请您帮我弄清楚如何保留来自客户端的原始请求 URL

【问题讨论】:

    标签: ruby proxy nginx thin unicorn


    【解决方案1】:

    我认为proxy_set_header 指令会有所帮助:

    location / {
        proxy_pass http://my_app_upstream;
        proxy_set_header Host $host;
        # ...
    }
    

    【讨论】:

    • 请注意其他人发现这一点:使 nginx 不操纵 URL 的解决方案的核心是删除 proxy_pass 指令末尾的斜杠。 http://my_app_upstreamhttp://my_app_upstream/
    • 对我来说,发生的事情是当 JSP 进行重定向时,my_app_upstream 主机名出现了。使用proxy_set_header Host $host 修改并使Tomcat/JSP 认为它是一个实际的客户端请求域。感谢您的帮助
    • @HugoJosefson 哇,感谢上帝,我注意到了你的帖子。这应该在答案中明确
    • 就我而言,@HugoJosefson 的解决方案不起作用。我指的是localhost:port;我必须设置标题。
    • 这是一个改进,但没有保留方案(http 或 https)。现在我的https://example.com/page uris 变成了http://example.com/page
    【解决方案2】:

    其他发现此问题的人的注意事项:解决方案的核心 nginx不是操纵网址,就是去掉末尾的斜杠 复制:proxy_pass 指令。 http://my_app_upstreamhttp://my_app_upstream/ – 雨果约瑟夫森

    我在上面的 cmets 中找到了这个,但我认为它确实应该是一个答案。

    【讨论】:

      【解决方案3】:

      nginx 还提供了 $http_host 变量,它将为您传递端口。 它是主机和端口的串联。

      所以你只需要这样做:

      proxy_set_header Host $http_host;
      

      【讨论】:

        【解决方案4】:

        对于我的身份验证服务器...这有效。我喜欢为我自己的人性化可读性提供 /auth 选项......或者我也通过端口/上游配置它以供机器到机器。

        .

        conf 开头

        ####################################################
        upstream auth {
            server 127.0.0.1:9011 weight=1 fail_timeout=300s;
            keepalive 16;
          }
        

        在我的 443 服务器块内

                  if (-d $request_filename) {
                  rewrite [^/]$ $scheme://$http_host$uri/ permanent;
              }
        
          location /auth {
                  proxy_pass http://$http_host:9011;
                  proxy_set_header Origin           http://$host;
                  proxy_set_header Host             $http_host:9011;
                  proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
                  proxy_set_header Upgrade          $http_upgrade;
                  proxy_set_header Connection       $http_connection;
                  proxy_http_version 1.1;
              }
        

        在conf的底部

        #####################################################################
        #                                                                   #
        #     Proxies for all the Other servers on other ports upstream     #
        #                                                                   #
        #####################################################################
        
        
        #######################
        #        Fusion       #
        #######################
        
        server {
            listen 9001 ssl;
        
        #############  Lock it down  ################
        
        # SSL certificate locations
            ssl_certificate /etc/letsencrypt/live/allineed.app/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/allineed.app/privkey.pem;
        
        # Exclusions
        
            include snippets/exclusions.conf;
        
        # Security
        
            include snippets/security.conf;
            include snippets/ssl.conf;
        
        # Fastcgi cache rules
        
            include snippets/fastcgi-cache.conf;
            include snippets/limits.conf;
            include snippets/nginx-cloudflare.conf;
        
        ###########  Location upstream ##############
        
            location  ~ / {
                proxy_pass http://auth;
                proxy_set_header Origin           http://$host;
                proxy_set_header Host             $host:$server_port;
                proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_set_header Upgrade          $http_upgrade;
                proxy_set_header Connection       $http_connection;
                proxy_http_version 1.1;
            }
                if (-d $request_filename) {
                rewrite [^/]$ $scheme://$http_host$uri/ permanent;
            }
        }
        

        【讨论】:

          【解决方案5】:

          如果某些东西修改了您尝试服务的位置,例如try_files,这样就保留了对后端的请求:

          location / {
            proxy_pass http://127.0.0.1:8080$request_uri;
          }
          

          【讨论】:

            【解决方案6】:

            在我的场景中,我通过 nginx vhost 配置中的以下代码实现了这一点

            server {
            server_name dashboards.etilize.com;
            
            location / {
                proxy_pass http://demo.etilize.com/dashboards/;
                proxy_set_header Host $http_host;
            }}
            

            $http_host 将在 Header 中设置与请求相同的 URL

            【讨论】:

              【解决方案7】:

              在不切断请求的absoluteURI 和标头中的Host 的情况下完美转发:

              server {
                  listen 35005;
              
                  location / {
                      rewrite            ^(.*)$   "://$http_host$uri$is_args$args";
                      rewrite            ^(.*)$   "http$uri$is_args$args" break;
                      proxy_set_header   Host     $host;
              
                      proxy_pass         https://deploy.org.local:35005;
                  }
              }
              

              在这里找到:https://opensysnotes.wordpress.com/2016/11/17/nginx-proxy_pass-with-absolute-url/

              【讨论】:

                【解决方案8】:

                只是 proxy_set_header 主机 $host 我的情况错过了端口。解决者:

                
                
                    location / {
                     proxy_pass http://BACKENDIP/;
                     include /etc/nginx/proxy.conf;
                    }
                
                

                然后在proxy.conf中

                
                
                    proxy_redirect off;
                    proxy_set_header Host $host:$server_port;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                
                

                【讨论】:

                • 谢谢,这是我缺少的部分($server_port),用于在代理后面的端点上进行 OAuth 验证。
                • 我在 sinatra 中使用机架保护,并且在 POST URL 上被禁止。将端口添加到主机代理标头为我修复了它。
                • 这在最新版本的 Nginx 中不再起作用我认为stackoverflow.com/questions/31482796/…
                猜你喜欢
                • 2016-11-02
                • 2017-05-12
                • 2015-03-16
                • 2018-10-30
                • 2023-03-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多