Rails – 确保www在URL中

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

我正在努力解决

  • 确保www在URL中,并且URL是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中?

谢谢

对于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中间件 。

 # 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项目使用的标准unit testing和集成测试工具来测试它,例如Test::UnitRSpec

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

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

在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 

我认为问题是你在Heroku上运行。 查看有关通配符域的Heroku文档:

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

 $ heroku addons:add wildcard_domains 

另请参阅将流量重定向到特定域 :

“如果您有多个域,或者您的应用程序的用户通过其Heroku子域访问它,但您之后切换到自己的自定义域,则可能需要让所有用户使用之前filter中的重定向到同一域中。像这样可以完成这项工作:“

 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 

试试这个

 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 

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

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

DNSimple提供了一个方便的URL重定向,此处从heroku-sslendpoint.com裸域重定向到www.heroku-sslendpoint.com子域。 在此处输入图像描述

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

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