导轨和HTTPS重定向(Rails redirect with https)

2019-09-15 03:42发布

我保持了Ruby on Rails的网站,我很困惑,如何执行重定向到使用HTTPS协议相对URL。

我可以成功地创建一个重定向到使用HTTP,例如相对URL:

redirect_to "/some_directory/"

但我不能辨别如何创建一个重定向到使用HTTPS协议的URL。 我只能够通过使用绝对URL,例如可以这样做:

redirect_to "https://mysite.com/some_directory/"

我想保持我的代码清洁,并使用相对URL似乎是一个不错的主意。 有谁知道如何在Rails中实现这一目标?

Answer 1:

你可能会更好过使用ssl_requirement ,如果一个链接不关心或重定向是或不使用HTTPS。 随着ssl_requirement,声明其行动需要SSL,哪些是能够SSL,哪些需要不使用SSL的。

如果你在你的Rails应用程序之外的某处重定向,然后指定协议作为奥利建议将工作。



Answer 2:

所述ActionController::Base#redirect_to方法有一个选项散列,参数的其中之一是:protocol ,它允许你拨打:

redirect_to :protocol => 'https://', 
            :controller => 'some_controller', 
            :action => 'index'

请参阅定义#redirect_to#url_for有关选项的更多信息。


另外,特别是如果SSL是用于所有控制器的操作,您可以使用采取更为声明性方法before_filter 。 在ApplicationController ,你可以定义如下方法:

def redirect_to_https
    redirect_to :protocol => "https://" unless (request.ssl? || request.local?)
end

然后,您可以在那些有需要SSL,如动作控制器添加过滤器:

class YourController
    before_filter :redirect_to_https, :only => ["index", "show"]
end

或者,如果您在您的整个应用程序需要SSL,宣布在过滤器中ApplicationController

class ApplicationController
    before_filter :redirect_to_https
end


Answer 3:

如果你想通过HTTPS提供整个应用程序则因为Rails的4.0要做到这一点,是让最好的办法force_ssl像这样的配置文件中:

# config/environments/production.rb
Rails.application.configure do
  # [..]

  # Force all access to the app over SSL, use Strict-Transport-Security,
  # and use secure cookies.
  config.force_ssl = true
end

默认情况下,这个选项是已经存在于config/environments/production.rb在新生成的应用程序中,但被注释掉了。

正如评论说,这将不只是重定向到https,而且还设置了Strict-Transport-Security头( HSTS ),并确保安全标志设置上的所有Cookie。 这两项措施提高应用程序的安全性没有显著的缺点。 它采用ActionDispatch:SSL

该HSTS到期设置默认设置为一年,不包括子域,这可能是罚款对于大多数应用。 您可以通过配置此hsts选项:

config.hsts = {
  expires: 1.month.to_i,
  subdomains: false,
}

如果你正在运行的Rails 3(> = 3.1)或不想使用https为整个应用程序,那么你可以使用force_ssl在一个控制器方法:

class SecureController < ApplicationController
  force_ssl
end

就这样。 你可以将它设置每个控制器,或在你ApplicationController 。 您可以强制有条件地使用熟悉的HTTPS ifunless选择; 例如:

# Only when we're not in development or tests
force_ssl unless: -> { Rails.env.in? ['development', 'test'] }


Answer 4:

这个答案是有点切原来的问题,但我记录下来的情况下,其他人在类似情况下对自己在这里结束了。

我曾在那里我需要有一个Rails的情况下使用https原在URL佣工等,即使所有请求的来源是未加密( http )。

现在,通常在这种情况下(这是正常的时Rails是后面的反向代理或负载平衡器等),所述x-forwarded-proto报头由反向代理设置也好,所以即使请求是所述代理与未加密的之间轨(可能不是的方式生产最好)钢轨认为一切都在https

我需要一个ngrok TLS隧道后面跑。 我想有ngrok终止与我指定letsencrypt证书的TLS。 然而,当它这样做,ngrok不提供自定义标题,包括设置能力x-forwarded-proto (尽管此功能在未来的某个时间计划)。

该解决方案被证明是非常简单:Rails不依赖于起源的或是否任一协议x-forwarded-proto直接设定,但在机架的环境变量rack.url_scheme 。 所以,我只是需要在发展中添加此Rack中间件:

class ForceUrlScheme
  def initialize(app)
    @app = app
  end

  def call(env)
    env['rack.url_scheme'] = 'https'
    @app.call(env)
  end
end


Answer 5:

如果要全局控制研究中控制器生成的URL的协议,则可以覆盖你的应用控制器url_options方法。 你可能会迫使取决于轨道ENV像这样生成的URL的协议:

 def url_options
    super
    @_url_options.dup.tap do |options|
      options[:protocol] = Rails.env.production? ? "https://" : "http://"
      options.freeze
    end
  end

这个例子中轨3.2.1工作,我不是为早期或未来版本完全确定。



Answer 6:

在轨道4可以使用force_ssl_redirect before_action实施SSL为单个控制器。 请注意,通过使用这种方法,您的cookie不会被标记为安全和HSTS不被使用。



Answer 7:

相对URL,顾名思义,使用当前的协议和主机。 如果你想改变正在使用的协议,需要提供绝对URL。 我会采取公正的意见和创造,这是否给你一个方法:

def redirect_to_secure(relative_uri)
  redirect_to "https://" + request.host + relative_uri
end


Answer 8:

打开具有类redirect_to ,并添加一个方法redirect_to_secure_of用合适的实现。 然后调用:

redirect_to_secure_of "/some_directory/"

将这个方法在lib目录或某处有用。



文章来源: Rails redirect with https