在Rails应用中,在通过HTTPS发送时,可以轻松地将会话cookie设置为包括secure
cookie属性,以确保该cookie不会通过非HTTP连接泄漏。
但是,如果Rails应用程序未使用HTTPS,而仅使用HTTP,则它似乎甚至都没有设置cookie。尽管这样做确实有些道理,但在这种情况下,有一个单独的前端负载平衡器,它负责终止SSL连接。从LB到Rails应用程序,连接仅是HTTP。
即使不使用HTTPS,如何强制Rails应用设置secure
cookie?
根据定义,安全cookie不会通过非安全连接发送。
在上游终止SSL很普遍,但是您需要传递某些标头字段,以使Rails知道并可以做正确的事情。
Here's a document详细解释了nginx的配置。搜索“设置标题”以跳到描述您需要通过的特定标题的部分。
[使用此配置有一些安全注意事项,例如,如果终止SSL的设备与Rails主机不在同一安全LAN上,则您存在漏洞。
我遇到了同样的问题,我用这种方法解决了:在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服务时它将完全杀死set 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