如何在rails中默认使cookie安全(仅限https)?
在Rails控制器中,我可以像这样设置一个cookie:
cookies[:foo] = "bar"
并指定“安全”(https-only)标志如下:
cookies[:foo, :secure => true] = "bar"
:secure
默认情况下, :secure
为false。 如何在应用程序范围内默认使用cookie?
这是在Rails 2.3.8上
不需要monkeypatch ActionController
/ ActionDispatch
, force_ssl
有副作用(例如在ELB后面 )。
实现安全cookie的最直接方法是修改config/initializers/session_store.rb
:
MyApp::Application.config.session_store :cookie_store, key: '_my_app_session', secure: Rails.env.production?
从rails 3.1开始,根据rails安全指南 ,您只需在application.rb
设置以下内容:
config.force_ssl = true
这会强制cookie仅通过https发送(我也会假设其他所有内容)。
谢谢@knx,你让我走上了正确的道路。 这是我想出的monkeypatch,它似乎正在起作用:
class ActionController::Response def set_cookie_with_security(key, value) value = { :value => value } if Hash != value.class value[:secure] = true set_cookie_without_security(key, value) end alias_method_chain :set_cookie, :security end
你怎么看?
快速而肮脏的解决方案:我认为可以通过修改action pack cookies模块中的[] =方法(actionpack / lib / action_controller / cookies.rb)
从:
def []=(name, options) if options.is_a?(Hash) options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options } options["name"] = name.to_s else options = { "name" => name.to_s, "value" => options } end set_cookie(options) end
至:
def []=(name, options) if options.is_a?(Hash) options.merge!({:secure => true}) options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options } options["name"] = name.to_s else options = { "name" => name.to_s, "value" => options } end set_cookie(options) end
# session only available over HTTPS ActionController::Base.session_options[:secure] = true
你应该看看rack-ssl-enforcer gem。 我只是在寻找一个干净的答案,它解决了问题,独立于你所使用的Rails版本,加上它是非常可配置的。