2011-06-13 44 views
14

我有一個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

回答

22

爲了西納特拉正確組裝用於重定向的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

1

您可以強制所有鏈接轉到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