2009-02-16 18 views
4

所以那種非常相似,「Detecting https requests in php」 HTTPS檢測HTTP VS服務器上:發回任何有用

希望有https://example.com/pog.phphttp://example.com/pog.php甚至反之亦然。

問題:

  • 無法讀取$ _SERVER什麼[「HTTPS」],因爲它不存在
  • 服務器發送通過端口80這兩個請求,所以無法檢查443對HTTPS版本
  • apache_request_headers()apache_response_headers()被髮回同樣的事情
  • 不能告訴負載平衡器任何東西,或把它發送額外出頭
  • 服務器反饋數據吐出來通過這兩個URL調用的頁面是完全一樣的保存會話ID。遊民。

是否有任何頁面方式檢測是否通過SSL或非SSL調用?

編輯$_SERVER["HTTPS"]不存在,無論是否打開,無論您是通過SSL還是非SSL查看網站。由於某種原因,託管服務器選擇了加密的所有HTTPS請求,但是端口爲80.因此,$_SERVER["HTTPS"]從不開啓,不在那裏,在該服務器端沒有任何有用的反饋。所以這個參數總是空的。

(和是的,這意味着它得到標記說FF或Chrome的部分無效的SSL證書。但這部分沒有關係。)

而且,可以從檢測URL中得到的最達到了斜線的地步。 PHP無法看到請求是否在前面有httpshttp

回答

22

關鍵字 - 負載均衡

的問題歸結爲一個事實,即負載平衡器處理SSL加密/解密,它是完全透明的網絡服務器。

Request: Client -> 443or80 -> loadbalancer -> 80 -> php 
Response: PHP -> 80 -> loadbalancer -> 443or80 -> Client 

這裏真正的問題是「你是否有過負載平衡器配置控制?」


如果你這樣做,有幾種方法來處理它。將負載均衡器配置爲具有HTTP和HTTPS的單獨服務定義。然後將HTTP流量發送到Web服務器的端口80,並將HTTPS流量發送到Web服務器的端口81。 (端口81不被別的使用)。

在Apache中,配置兩個不同的虛擬主機:

<VirtualHost 1.2.3.4:80> 
    ServerName foo.com 
    SetEnv USING_HTTPS 0 
    ... 
</VirtualHost> 

<VirtualHost 1.2.3.4:81> 
    ServerName foo.com 
    SetEnv USING_HTTPS 1 
    ... 
</VirtualHost> 

然後,將環境變量USING_HTTPS將或者1 | 0,具體取決於哪個虛擬主機提取它。這將在PHP中的$_SERVER數組中可用。這不是很酷嗎?


如果您沒有訪問負載均衡配置,那麼事情有點棘手。如果您使用HTTP或HTTPS,將無法確切知道,因爲HTTP和HTTPS是協議。它們指定如何連接以及通過哪種格式發送信息,但無論哪種情況,您都使用HTTP 1.1來發出請求。實際請求中沒有信息說明是HTTP還是HTTPS。

但是不要灰心。有幾個想法。

PHP的setcookie()函數的第6個參數可以指示客戶端僅通過HTTPS連接發送cookie(http://www.php.net/setcookie)。也許你可以用這個參數設置一個cookie,然後在隨後的請求中檢查它?

另一種可能性是使用JavaScript根據協議更新每個頁面上的鏈接(添加GET參數)。

(都以上是防彈的)

另一種務實的選擇是得到一個不同的域的SSL,如secure.foo.com。然後你可以使用上面的VirtualHost技巧。


我知道這是不是最簡單的問題,因爲我白天(後面有SSL模塊的Cisco CSS負載均衡負載平衡Web集羣)處理。最後,您可以始終認爲您的Web應用程序應在需要時切換到SSL模式,並相信用戶不會將其移回(畢竟,這是他們的數據(通常))。

希望它有一點幫助。

+1

永遠不要相信用戶。頁面必須保持在HTTP版本上,所以如果他們嘗試使用HTTPS,他們會被回擊到HTTP版本。雖然喜歡你的回答。 – random 2009-02-16 05:53:10

4
$ _SERVER [「HTTPS」]不存在,無論是否打開,無論您是通過SSL還是非SSL查看網站。由於某種原因託管已選擇加密所有HTTPS請求,但端口80.因此,$ _SERVER [「HTTPS」]從未打開,不在那裏,只是沒有有用的反饋在該服務器點。所以這個參數總是空的。

您必須確保提供商在您的站點的VHOST條目中包含以下行:SSLOptions +StdEnvVars。該行告訴Apache在您的腳本環境中包含SSL變量(PHP)。