2011-12-13 48 views
5

我現在有一個設置,其中我強迫SSL或HTTP,我這個的before_filter需要它在我的應用程序控制器:主機使用Rails 3.1

def force_ssl 
    if params[:controller] == "sessions" 
    if !request.ssl? && Rails.env.production? 
     redirect_to :protocol => 'https://', :status => :moved_permanently 
    end 
    else 
    if request.ssl? && Rails.env.production? 
     redirect_to :protocol => 'http://', :status => :moved_permanently 
    end 
    end 
end 

我希望做的是在使用SSL時使用https://secure.example.com,但在不使用SSL時請使用http://example.com。有沒有辦法根據我是否使用SSL在主機名之間切換?

+0

何苦強迫用戶通過SSL時驗證,只要進行身份認證,任何人都可以破解他們與例如會議firesheep,免費會話黑客firefox插件。如果您嘗試以這種方式使用SSL,則無法保護用戶。相反,如果您的站點的某些部分需要通過SSL進行交付,那麼從實際的安全角度來看,您的站點的每個部分都可能需要通過SSL進行交付(或至少在身份驗證後的每個部分)。 – yfeldblum

回答

4

首先我將介紹如何在當前版本和早期版本的Rails中強制使用SSL,然後在最後發佈瞭如何在並行中使用HTTP和HTTPS,這正是我想要的。

滑軌> = 3.1

只需在您的環境配置使用config.force_ssl = true

# config/application.rb 
module MyApp 
    class Application < Rails::Application 
    config.force_ssl = true 
    end 
end 

您還可以選擇性地啓用https,具體取決於當前的Rails環境。例如,您可能希望在開發時關閉HTTPS,並在分段/生產中啓用它。

# config/application.rb 
module MyApp 
    class Application < Rails::Application 
    config.force_ssl = false 
    end 
end 

# config/environments/production.rb 
MyApp::Application.configure do 
    config.force_ssl = true 
end 

Rails的< 3.1

萬一你有沒有Rails的3.1和想的一樣功能的任何項目。通過將以下行添加到您的環境配置中來啓用HTTPS。

config.middleware.insert_before ActionDispatch::Static, "Rack::SSL"

注意,我傳遞Rack::SSL作爲字符串委託類的裝載在Rails應用程序初始化結束。另請注意,中間件必須插入堆棧中的特定位置,至少在ActionDispatch::StaticActionDispatch::Cookies之前。

不要忘記在您的Gemfile中定義Rack :: SSL依賴關係。

# Gemfile 
gem 'rack-ssl', :require => 'rack/ssl' 

啓用HTTPS和HTTP並行

Rack::SSL有一個非常有趣的和未公開的特性。您可以通過:exclude選項來確定何時啓用/禁用HTTPS的使用。

以下代碼僅在請求來自HTTPS連接時啓用Rack::SSL及其所有篩選器。

config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env| env['HTTPS'] != 'on' } 

以下兩個網址將繼續工作,但第一個將觸發Rack::SSL過濾器。

https://secure.example.com
http://example.com

+0

我在使用force_ssl之前(我在Rails 3.1中),但是我沒有找到一種方法來強制http,因爲我不想使用SSL,所以我只是在自己的應用程序控制器中推出了自己的解決方案。有沒有辦法自定義force_ssl? –

+0

你可以在ForceSSL模塊中寫一個自定義的類方法,它可以做到與ForceSSL相反的功能,如果你願意,我可以發佈一個例子嗎? – digicazter