12

在 Rails 应用程序中,可以轻松地将会话 cookie 设置为包含securecookie 属性,当通过 HTTPS 发送以确保 cookie 不会通过非 HTTP 连接泄漏时。

但是,如果 Rails 应用程序不使用 HTTPS,而仅使用 HTTP,那么它似乎根本没有设置 cookie。
虽然这确实有些道理,但在这种情况下,有一个单独的前端负载平衡器,负责终止 SSL 连接。从 LB 到 Rails 应用程序的连接仅是 HTTP。

secure即使不使用 HTTPS, 如何强制 Rails 应用设置cookie?

4

3 回答 3

11

根据定义,安全 cookie 不会通过非安全连接发送。

终止 SSL 上游很常见,但是您需要传递某些标头字段,以便 Rails 知道并可以做正确的事情。

这是一个文档,它非常详细地解释了 nginx 的配置。搜索“设置标题”以跳转到描述您需要通过的特定标题的部分。

使用此配置存在安全考虑,例如,如果终止 SSL 的设备与 Rails 主机不在同一个安全 LAN 上,那么您就有漏洞。

于 2013-02-21T13:49:09.257 回答
0

同样的问题发生在我身上,我这样解决了:在 session_store.rb 我配置:

MyApp::Application.config.session_store :cache_store, key: COOKIE_NAME, :expire_after => 1.days, :expires_in => 1.days, :domain => 'mydomain.com', same_site: :none

(注意我没有放在, same_site: :none这里,因为它会在服务 HTTP 时完全杀死设置的 cookie)

initializers然后我通过将这个文件放在文件夹中来修补 Rack->Utils->set_cookie_header

require 'rack/utils'
module Rack
  module Utils
    def self.set_cookie_header!(header, key, value)
      case value
      when Hash
        domain  = "; domain="  + value[:domain] if value[:domain]
        path    = "; path="    + value[:path]   if value[:path]
        max_age = "; max-age=" + value[:max_age] if value[:max_age]
        expires = "; expires=" +
            rfc2822(value[:expires].clone.gmtime) if value[:expires]

        # Make secure always, even in HTTP
        # secure = "; secure"  if value[:secure]
        secure = "; secure"

        httponly = "; HttpOnly" if value[:httponly]
        same_site =
            case value[:same_site]
            when false, nil
              nil
            when :none, 'None', :None
              '; SameSite=None'
            when :lax, 'Lax', :Lax
              '; SameSite=Lax'
            when true, :strict, 'Strict', :Strict
              '; SameSite=Strict'
            else
              raise ArgumentError, "Invalid SameSite value: #{value[:same_site].inspect}"
            end
        value = value[:value]
      end
      value = [value] unless Array === value
      cookie = escape(key) + "=" +
          value.map { |v| escape v }.join("&") +
          "#{domain}#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"

      case header["Set-Cookie"]
      when nil, ''
        header["Set-Cookie"] = cookie
      when String
        header["Set-Cookie"] = [header["Set-Cookie"], cookie].join("\n")
      when Array
        header["Set-Cookie"] = (header["Set-Cookie"] + [cookie]).join("\n")
      end

      nil
    end
  end
end
于 2020-04-02T11:15:27.133 回答
0

基本问题是,根据Set-Cookie的定义,具有安全集的 cookie 只能通过安全连接发送。
因此,不通过 HTTP 发送带有安全设置的 cookie 是预期的行为。

您可能希望在不同的环境中设置不同的 cookie 选项。在 config/environments/developent.rb 你可以设置

Rails.application.configure do
  config.session_store :cache_store, key: COOKIE_NAME, same_site: :none
end

在生产环境 (config/environments/production.rb) 中,您使用 HTTPS 部署站点:

Rails.application.configure do
  config.session_store :cache_store, key: COOKIE_NAME, same_site: :lax, secure: true
end
于 2020-11-11T10:48:44.820 回答