Rails 3.1中Heroku中ssl特定的主机名



我目前在我的应用程序控制器中使用这个before_filter强制SSL或http设置:

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在主机名之间切换?

首先我将展示如何在当前和早期版本的Rails中强制使用SSL,然后在最后我发布了如何并行使用HTTP和HTTPS,这是我认为你正在寻找的。

Rails>= 3.1

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

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

您还可以根据当前的Rails环境选择性地启用https。例如,您可能希望在开发阶段关闭HTTPS,而在登台/生产阶段启用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 & lt;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' }

下面两个url将继续工作,但第一个将触发Rack::SSL过滤器。

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