Rails - 确保www在URL中

时间:2010-12-07 02:35:39

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

我的应用程序托管在Heroku上,并拥有www.mysite.com的证书

我正在努力解决

  • 确保www在网址中,并且网址为HTTPS

这是我到目前为止所拥有的:

class ApplicationController < ActionController::Base
before_filter :check_uri

  def check_uri
    redirect_to request.protocol + "www." + request.host_with_port + request.request_uri if !/^www/.match(request.host) if Rails.env == 'production'
  end

但这似乎没有起作用。任何建议或可能不同的方法来解决确保HTTP和www。在URL?

由于

6 个答案:

答案 0 :(得分:12)

对于SSL,请使用rack-ssl

# config/environments/production.rb
MyApp::Application.configure do
  require 'rack/ssl'
  config.middleware.use Rack::SSL
  # the rest of the production config....
end

对于WWW,请创建自己的Rack middleware

# lib/rack/www.rb
class Rack::Www
  def initialize(app)
    @app = app
  end
  def call(env)
    if env['SERVER_NAME'] =~ /^www\./
      @app.call(env)
    else
      [ 307, { 'Location' => 'https://www.my-domain-name.com/' }, '' ]
    end
  end
end

# config/environments/production.rb
MyApp::Application.configure do
  config.middleware.use Rack::Www
  # the rest of the production config....
end

要在浏览器中对此进行测试,您可以编辑本地开发计算机上的/etc/hosts文件

# /etc/hosts
# ...
127.0.0.1 my-domain-name.com
127.0.0.1 www.my-domain-name.com

在本地开发计算机上以生产模式运行应用程序

$ RAILS_ENV=production rails s -p 80

并浏览到http://my-domain-name.com/,看看会发生什么。

在测试期间,您可能想要注释掉重定向到HTTPS站点的行。

可能还有一些方法可以使用许多Rails项目使用的标准单元测试和集成测试工具对其进行测试,例如Test::UnitRSpec

答案 1 :(得分:3)

Pivotal Labs有一些名为Refraction的中间件,它是mod_rewrite的替代品,除了它存在于源代码而不是Apache配置中。

对于你需要的东西可能有点过分,但它很容易处理这些东西。

答案 2 :(得分:1)

在Rails 3中

#config/routes.rb
Example::Application.routes.draw do
  redirect_proc = Proc.new { redirect { |params, request|
    URI.parse(request.url).tap { |x| x.host = "www.example.net"; x.scheme = "https" }.to_s
  } }
  constraints(:host => "example.net") do
    match "(*x)" => redirect_proc.call
  end
  constraints(:scheme => "http") do
    match "(*x)" => redirect_proc.call
  end
  # .... 
  # .. more routes ..
  # ....
end

答案 3 :(得分:0)

我认为问题是你在Heroku上运行。查看关于Wildcard domains的Heroku文档:

“如果您希望自己的应用响应自定义域名下的任何子域名(如* .yourdomain.com),则需要使用通配符域加载项。...”

$ heroku addons:add wildcard_domains

另请参阅Redirecting Traffic to Specific Domain

“如果您有多个域,或者您的应用有用户通过其Heroku子域访问它,但您之后切换到自己的自定义域,则可能希望让所有用户都使用之前的重定向进入同一域过滤器。像这样的东西可以完成这项工作:“

class ApplicationController
  before_filter :ensure_domain

  TheDomain = 'myapp.mydomain.com'

  def ensure_domain
    if request.env['HTTP_HOST'] != TheDomain
      redirect_to TheDomain
    end
  end
end

答案 4 :(得分:0)

试试这个

def check_uri
  if Rails.env == 'production' && request && (request.subdomains.first != "www" || request.protocol != 'https://')
    redirect_to "https://www.mysite.com" + request.path, :status => 301 and return
  end
end

答案 5 :(得分:0)

您最好的选择是设置与DNS提供商的重定向,以便在任何请求到达您的服务器之前很久就会发生。来自Heroku Dev Center

  

子域重定向导致301永久重定向到指定子域的所有对裸域的请求,以便正确路由所有当前和未来请求,并在用户的位置字段中显示完整的www主机名。

     

DNSimple提供了一个方便的URL重定向,此处可以从中重定向   heroku-sslendpoint.com裸域到   www.heroku-sslendpoint.com子域名。   enter image description here

     

为了在Heroku上正确配置,www子域应该是a   CNAME记录对yourappname.herokuapp.com的引用。

这不仅仅是DNSimple。我的DNS提供商是123 Reg,他们支持它,但称之为web forwarding