机架在force_ssl Rails之前重写> 3.2 Heroku

时间:2013-05-31 17:16:47

标签: ruby-on-rails heroku rack

我正在使用Rack Rewrite将我的apex / root域重定向到我的www域,因为我的通配符SSL不支持根域。我还想在整个网站范围内强制使用SSL,但似乎无法在强制SSL之前进行重写。我尝试了一些方法,即答案中的回答:https://stackoverflow.com/a/8217170/535632

这是我的重写代码:

Gospot::Application.config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do

    if Rails.env.production?
        r301 %r{.*}, Proc.new {|path, rack_env| "http://www.#{rack_env['SERVER_NAME']}#{path}" }, 
                :if => Proc.new {|rack_env| rack_env['SERVER_NAME'] == 'mydomain.com'}
    end
end

我试过了:

require 'rack/ssl'
Gospot::Application.config.middleware.insert_before(Rack::SSL, Rack::Rewrite) do

而不是在config.force_ssl = true中使用production.rb,但我在Heroku上收到以下错误:

No such middleware to insert before: Rack::SSL (RuntimeError)

无论如何在force_ssl之前运行我的机架重写?我找到了很多答案,但它们似乎都适用于Rails< 3.1

3 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,我想在强制SSL之前使用rack-rewrite来重定向域。通过在ActionDispatch :: SSL之前插入Rack :: Rewrite中间件,我能够在Rails 4中实现这一点,如下面的代码所示。

config.middleware.insert_before(ActionDispatch::SSL, Rack::Rewrite) do 
  # redirects / rewrites here
end

答案 1 :(得分:1)

最简单的方法(取决于您的DNS提供商)会使您的顶级DNS记录成为www子域的CNAME。

如果这对您不起作用,那么您应该找到堆栈中存在的中间件,以便之前进行此重写。试试这个:

heroku run rake middleware

了解中间件堆栈的外观。选择一个相对较高的链中间件并将重写放在它之前。肯定会有一些猜测和检查,但这最终会纠正你的问题。

答案 2 :(得分:0)

我遇到了同样的问题(Rails 3)。显然,force_ssl将Rack:SSL添加到中间件的顶部。要在它之前插入,你必须将它作为一个字符串添加,否则你将得到一个"未初始化的常量"错误。

以下是我最终使用的代码:

SM::Application.config.middleware.insert_before("Rack::SSL", Rack::Rewrite) do
  # rewrite code
end