如何在 rails 应用程序中手动设置 cookie?
How do I manually set cookie in rails app?
我有一种情况需要在自定义 header 中发送 session id,因为 Safari 不允许从 iframe 发送 cookie。
但是现在,我无法从机架中间件设置 cookie。
status, headers, body = @app.call(env)
session_id = headers['X-SESSION-ID'] || headers['HTTP_X_SESSION_ID'] || headers['x-session-id'] || ''
if !headers['Cookie'].present? && session_id.present?
headers['Cookie'] = {
'_session_id': {
value: session_id,
path: '/',
httpOnly: true
}
}
end
或者有没有办法手动设置 session id 而不必从 cookie 中获取它?
更新 1:
修改机架请求文件确实有效。但是,我不确定如何进行此操作。如果没有任何效果,我可能会在所有服务器中手动更新此文件。
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"] || "_session_id=#{@env["HTTP_X_SESSION_ID"]}"
return hash if string == @env["rack.request.cookie_string"]
hash.clear
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k,v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash
end
像上面那样修改cookie方法好像不行。
最后我设法解决了它。所以,我在 initializers
中添加了 rack_request.rb
。这是它的代码:
require 'rack'
require 'rack/request'
require 'rack/utils'
Rack::Request.class_eval do
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"] || "_session_id=#{@env['HTTP_X_SESSION_ID']}"
unless string =~ /\s*_session_id=/i
if @env['HTTP_X_SESSION_ID'].present?
string << "; _session_id=#{@env['HTTP_X_SESSION_ID']}"
end
end
# require 'colorize'
#
# Rails.logger.info 'from cookies'.green
# Rails.logger.info (string.blue)
return hash if string == @env["rack.request.cookie_string"]
hash.clear
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Rack::Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k, v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash
end
end
我在我的 ajaxHeaders 中发送 'X-SESSION-ID'
作为会话 ID。
我有一种情况需要在自定义 header 中发送 session id,因为 Safari 不允许从 iframe 发送 cookie。
但是现在,我无法从机架中间件设置 cookie。
status, headers, body = @app.call(env)
session_id = headers['X-SESSION-ID'] || headers['HTTP_X_SESSION_ID'] || headers['x-session-id'] || ''
if !headers['Cookie'].present? && session_id.present?
headers['Cookie'] = {
'_session_id': {
value: session_id,
path: '/',
httpOnly: true
}
}
end
或者有没有办法手动设置 session id 而不必从 cookie 中获取它?
更新 1:
修改机架请求文件确实有效。但是,我不确定如何进行此操作。如果没有任何效果,我可能会在所有服务器中手动更新此文件。
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"] || "_session_id=#{@env["HTTP_X_SESSION_ID"]}"
return hash if string == @env["rack.request.cookie_string"]
hash.clear
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k,v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash
end
像上面那样修改cookie方法好像不行。
最后我设法解决了它。所以,我在 initializers
中添加了 rack_request.rb
。这是它的代码:
require 'rack'
require 'rack/request'
require 'rack/utils'
Rack::Request.class_eval do
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"] || "_session_id=#{@env['HTTP_X_SESSION_ID']}"
unless string =~ /\s*_session_id=/i
if @env['HTTP_X_SESSION_ID'].present?
string << "; _session_id=#{@env['HTTP_X_SESSION_ID']}"
end
end
# require 'colorize'
#
# Rails.logger.info 'from cookies'.green
# Rails.logger.info (string.blue)
return hash if string == @env["rack.request.cookie_string"]
hash.clear
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
cookies = Rack::Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
cookies.each { |k, v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash
end
end
我在我的 ajaxHeaders 中发送 'X-SESSION-ID'
作为会话 ID。