如何解决Sinatra重定向https到http下nginx

问题描述:

我有一个Sinatra应用程序运行在nginx(使用瘦作为后退代理),我在Sinatra中使用redirect '/<path>'语句。但是,当我通过https访问该网站时,这些重定向将它们发送到http://localhost/<path>而不是它们应该的https://localhost/<path>如何解决Sinatra重定向https到http下nginx

目前Nginx的将控制权交给薄与此命令proxy_pass http://thin _cluster,其中thin_cluster

upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; } 

我该如何解决这个问题?

+0

在你的'proxy_pass'行帮助后添加'proxy_set_header X-Forwarded-Proto $ scheme;'吗? – matt 2011-06-14 22:44:35

+0

你应该写这个答案......它解决了我的问题。谢谢! – 2011-06-15 19:04:38

为了西纳特拉正确组装用于重定向的URL,它需要能够确定请求是否使用ssl,以便可以根据情况使用httphttps进行重定向。

很明显,实际调用精简并不使用ssl,因为这是由前端Web服务器处理的,并且代理请求处于明确状态。因此,我们需要一种方法来告诉Sinatra它应该将请求视为安全的,尽管它实际上并未使用ssl。

最终确定请求是否应视为安全的代码位于Rack::Request#ssl?Rack::Request#scheme方法中。方法scheme检查env散列以查看是否存在多个条目之一。其中之一是HTTP_X_FORWARDED_PROTO,它对应于X-Forwarded-Proto HTTP标头。如果设置了该值,则将该值用作协议方案(httphttps)。

因此,如果我们在将请求从nginx代理到后端时将此HTTP头添加到请求中,Sinatra将能够正确确定何时重定向到https。在nginx中,我们可以向代理请求添加头文件proxy_set_header,该方案可用于$scheme variable

因此增加线路

proxy_set_header X-Forwarded-Proto $scheme; 

到nginx的配置proxy_pass行后应该使其工作。

+0

由于某种原因,这搞砸了我的标题中的主机字段,发送我所有的redirect_to到无效的域。添加“proxy_set_header主机$主机”修复它。 (我的应用程序在sub-uri下运行,我想知道这是否是个问题。) – bioneuralnet 2011-07-17 20:54:36

+2

@bioneuralnet你也可以使用'X-Forwarded-Host',在检查'Host'头文件之前进行机架检查。我看起来不像nginx自动添加这些头,但Apache在mod_proxy中。 – matt 2011-07-17 21:32:39

+1

是的,我想这也可以。在http://wiki.nginx.org/HttpProxyModule#proxy_set_header上找到了一个有趣的解释。我在http块中设置了proxy_set_header主机,用于我所有的应用程序。根据您的文章,我在位置@myapp中添加了proxy_set_header X-Forwarded-Proto。根据文档,“只有在给定级别没有发布proxy_set_header指令时,才会继承上级发布的proxy_set_header指令。” 所以我在@myapp的“本地”proxy_set_header调用清除了我的“全局”proxy_set_header调用,即使它们是针对不同的字段。 – bioneuralnet 2011-07-17 21:39:02

您可以强制所有链接转到https的nginx图层。 在nginx.conf:

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

这是好事,有太多,以确保您的要求总是HTTPS

+0

这是有帮助的...但不回答我问的问题。如果服务器以仅HTTPS模式运行,我已经具有此功能;当我想接受HTTPS和HTTP时,我的问题就会发生。 – 2011-06-15 19:05:25