在force_ssl之前重定向到'www'

时间:2011-09-21 21:34:45

标签: ruby-on-rails ruby-on-rails-3 ssl heroku

我正在将应用程序移动到heroku,并且遇到了ssl和重定向问题。

我在rails 3.1上,我尝试在环境production.rb中使用中间件强制使用ssl。我已经尝试将它添加到应用程序控制器中。

问题是,当我执行ssl的完整站点强制时,我无法在达到SSL要求之前重定向到www。这很重要,因为如果用户访问https://mydomain.com,将会显示错误的SSL证书警告。如果他们继续,他们就会重定向到'www'。

SSL强制正在运行,重定向到'www'子域工作正常,我只需要先重定向。

有什么想法吗?

Per Nathan的评论:

我有一个不完美的解决方案。我的root_path不强制ssl。所有包含敏感信息的部分都会强制它。到达后,所有流量都会通过我的routes.rb指向www:

constraints(:host => "domain.com") do
  match "(*x)" => redirect { |params, request|
    URI.parse(request.url).tap { |x| x.host = "www.domain.com" }.to_s
  }
  end 

这可能会隐藏大部分问题,因为当用户点击登录或其他任何内容时,他们现在都在www域。浏览器不会发出有关证书的警告。这对于某个项目来说很好。另一个项目我最终为签署的外卡证书支付了大笔费用。

抱歉,这不是一个真正的解决方案。如果你转到https://domain.com/forcedsslpath,项目仍会提供安全警告。

3 个答案:

答案 0 :(得分:2)

由于您的301是由应用程序发送的,并且请求在访问中间件(运行rack-ssl之前)之前甚至无法访问应用程序,因此您唯一的解决方案是更改中间件或进行重定向它甚至击中了中间件。

对于后者,你必须在Heroku周围捅。我自己不用它。在VPS部署中,您只需在面向前端的Web服务器(Apache,nginx)上添加重定向,然后再访问中间件。这似乎是一个常见的情况,所以我想Heroku可能会为你提供一些东西。

对于前者,它应该不难。 rack-ssl中间件非常非常简单,根据您的需要进行monkeypatch它应该不难。

https://github.com/josh/rack-ssl/blob/master/lib/rack/ssl.rb#L58

我想像url.host = "www.myhost.com"这样的东西可能就是你想要的东西(虽然你可能会说可能有更多与FQDN无关的方法)。

答案 1 :(得分:2)

以下是我解决问题的方法。我从config.force_ssl = true中删除了production.rb,而是使用了:

将此方法添加到ApplicationController

  def force_ssl
    if Rails.env.production?
      redirect_to :protocol => 'https' unless request.ssl?
    end
  end  

并将其添加为ApplicationController

上的前置过滤器
before_filter :force_ssl

我也在使用从http://example.com切换到http://www.example.comensure_domain。确保在force_ssl之前调用此类过滤器。

答案 2 :(得分:1)

您应该可以通过在force_ssl中间件之前运行机架重定向来实现此目的。

这篇文章向您展示了如何做到这一点。

http://blog.dynamic50.com/2011/02/22/redirect-all-requests-for-www-to-root-domain-with-heroku/

希望这有帮助。