Set “secure” flag on session cookie in RoR even over HTTP

后端 未结 3 2144
没有蜡笔的小新
没有蜡笔的小新 2021-02-20 14:39

In a Rails app, the session cookie can be easily set to include the secure cookie attribute, when sending over HTTPS to ensure that the cookie is not leaked over a

3条回答
  •  走了就别回头了
    2021-02-20 15:28

    The same problem happened to me, and I solved it this way: In session_store.rb I configured:

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

    (note that I didn't put the , same_site: :none here, because it would kill the set cookie completely when serving HTTP)

    And then I monkey patched the Rack->Utils->set_cookie_header, by placing this file in the initializers folder

    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
    

提交回复
热议问题