Ruby-on-rails 如何在 Rails 中默认使 cookie 安全(仅限 https)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3773605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:15:18  来源:igfitidea点击:

How can I make cookies secure (https-only) by default in rails?

ruby-on-railscookieshttpsssl

提问by John Bachir

In a Rails controller, I can set a cookie like this:

在 Rails 控制器中,我可以像这样设置 cookie:

cookies[:foo] = "bar"

And specify that the "secure" (https-only) flag be on like this:

并指定“安全”(仅限 https)标志如下:

cookies[:foo, :secure => true] = "bar"

:secureis false by default. How can I have cookies be secure by default, application-wide?

:secure默认为假。默认情况下,如何让 cookie 在整个应用程序范围内都是安全的?

This is on Rails 2.3.8

这是在 Rails 2.3.8 上

采纳答案by John Bachir

Thanks @knx, you sent me down the right path. Here's the monkeypatch I came up with, which seems to be working:

谢谢@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

What do you think?

你怎么认为?

回答by David Cain

There's no need to monkeypatch ActionController/ActionDispatch, and force_sslhas side effects (e.g. when behind an ELB).

不需要monkeypatch ActionController/ ActionDispatch,并且force_ssl有副作用(例如在ELB 后面时)。

The most straightforward way to achieve secure cookies is to modify config/initializers/session_store.rb:

实现安全 cookie 的最直接方法是修改config/initializers/session_store.rb

MyApp::Application.config.session_store :cookie_store, key: '_my_app_session',
                                                       secure: Rails.env.production?

回答by Markus

starting with rails 3.1, according to the rails security guide, you can simply set the following in your application.rb:

从 rails 3.1 开始,根据rails security guide,您可以简单地在您的application.rb:

config.force_ssl = true

this forces the cookie to be sent over https only (and I assume everything else, too).

这会强制 cookie 仅通过 https 发送(我也假设其他所有内容)。

回答by Imran Ahmad

To force SSL and enable the secure cookie for an entire Ruby on Rails application, enable force_ssl in your environment file such as production.rb.

要强制 SSL 并为整个 Ruby on Rails 应用程序启用安全 cookie,请在您的环境文件(例如 production.rb)中启用 force_ssl。

# config/environments/production.rb
config.force_ssl = true

If you need to support HTTP and HTTPS traffic with your Ruby on Rails application, set the secure cookie flag for your application so that session cookies are ONLY sent over HTTPS.

如果您的 Ruby on Rails 应用程序需要支持 HTTP 和 HTTPS 流量,请为您的应用程序设置安全 cookie 标志,以便会话 cookie 仅通过 HTTPS 发送。

The consequence is you can no longer maintain session state over HTTP, but you at least protect yourself from session hiHymaning attacks.

结果是您无法再通过 HTTP 维护会话状态,但您至少可以保护自己免受会话劫持攻击。

# config/initializers/session_store.rb
# set secure: true, optionally only do this for certain Rails environments (e.g., Staging / Production
Rails.application.config.session_store :cookie_store, key: '_testapp_session', secure: true

Hereis the video tutorial of same.

是相同的视频教程。

回答by alsotang

# session only available over HTTPS
ActionController::Base.session_options[:secure] = true

回答by knx

Quick and dirty solution: i think it is possible by modifying []= method in action pack cookies module (actionpack/lib/action_controller/cookies.rb)

快速而肮脏的解决方案:我认为可以通过修改动作包cookies模块(actionpack/lib/action_controller/cookies.rb)中的[]=方法

from:

从:

    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

to:

到:

    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

回答by brightball

You should look at the rack-ssl-enforcer gem. I was just looking for a clean answer to this and it solves the problem independent of which version of Rails you're on, plus it's extremely configurable.

您应该查看 rack-ssl-enforcer gem。我只是在寻找一个干净的答案,它解决了与您使用的 Rails 版本无关的问题,而且它的可配置性非常强。