我保持了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 if
或unless
选择; 例如:
# 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