我检查了名为ssl_requirement
的宝石,它在某些操作上强制执行SSL并增强了网址和路径帮助程序,整体看起来很有希望,但它太过时而且维护得不太好。
有没有人知道提供这种便利的任何更新替代方案:
https://
,而不必破坏代码::protocol => 'https'
?答案 0 :(得分:3)
你不需要宝石 - 你可以写一个小帮手来做这件事。
ApplicationController中的:
def force_ssl(options = {})
host = options.delete(:host)
unless request.ssl? or Rails.env.development?
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
redirect_options.merge!(:host => host) if host
flash.keep
redirect_to redirect_options and return
else
true
end
end
然后在你的控制器中:
before_filter :force_ssl, :only => [:login]
这不满足您在路径助手上自动选择https协议的第二个要求,但是使用控制器指定的SSL执行无法实现,因为路由助手并不关心发生了什么在控制器级别上。这实际上与控制器强制SSL互斥,因为如果您的路由指定HTTPS,则它们不会将非HTTPS URL解析为控制器操作,这意味着您的force_ssl
过滤器永远不会被命中。但是,您可以通过复制路由来实现此目的,以便同时具有HTTPS范围和未范围的路由,并在HTTPS范围的路由之前定义未范围的路由,以便HTTPS范围的版本采用帮助程序名称。但这确实意味着重复。
但是,您可以通过一个小帮助方法实现这一点。我没有对此进行测试,但这个概念应该有效:
def route_with_https_preference(&block)
&block.call
scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
instance_eval &block
end
end
route_with_https_preference do
resources :gizmos do
resources :widgets
end
end
您可以轻松地在路径文件中实现SSL范围的路由(有关详细信息,请参阅this answer),但这确实意味着您必须使用_url
帮助程序而不是_path
} helper,因为协议交换机需要一个完全限定的URL。