如何在单个机架应用程序中与多个会话cookie(针对不同的路径或域)进行交互?
例如,考虑使用3个位置的以下应用程序:
应该可以与3个会话cookie进行交互:
Rack :: Session :: Cookie似乎是一个不错的选择,但作为中间件,会话cookie必须在config.ru中设置,并且似乎仅限于每个机架应用程序一个会话cookie。
在这种特殊情况下,主机架应用程序点是轻松添加子应用程序,因此将应用程序划分到多个机架应用程序中以使用Rack :: Session :: Cookie不是一个可行的解决方案。
理想的方法是从机架应用程序代码中自由地与多个会话cookie进行交互。
目前,我正在考虑:
但两者都很乏味,所以我想知道是否有更简单的方法来实现这个功能。
提前感谢任何建议或建议。
答案 0 :(得分:3)
如果有人以相同的需求运行,我发现创建一个类来管理应用程序内的会话是最简单的方法。
Rack :: Utils有两个很好的快捷方式Rack::Utils.set_cookie_header!和Utils.delete_cookie_header!,可以在处理Cookie时让事情变得更轻松。
我在使用我的应用程序的数据库中保存会话,但支持另一个后端应该是微不足道的。
作为旁注,我附带了一些注意事项:
管理cookie的类,提交功能集和删除cookie到机架。
class Framework::Response::Cookies
def set( params )
@cookies[params.delete( :name )] = params
end
def remove( params )
@remove_cookies[params.delete( :name )] = params
end
def commit( headers )
@cookies.each_pair do |name, params|
Rack::Utils.set_cookie_header!( headers, name, params )
end
@remove_cookies.each_pair do |name, params|
Rack::Utils.delete_cookie_header!( headers, name, params )
end
end
end
管理会话的类(使用Mongo作为后端):
class Database::Mongo::Session < Session
def save
expire = Time.now + @session_ttl
@framework.content.db.find_and_modify( self.collection_name, {
:query => { :name => @session_name, :id => @session_id },
:update => { :expire => expire, :name => @session_name, :id => @new_session_id || @session_id , :variables => @variables.to_hash },
:upsert => true
})
@framework.response.cookies.set(
:name => @session_name,
:value => @new_session_id || @session_id,
:path => @framework.applications.active.active_request['path'],
:domain => @framework.applications.active.active_request['host'],
:httponly => true
)
end
def delete
@framework.content.db.remove( self.collection_name, { :id => @session_id } )
@framework.response.cookies.remove( :name => @session_name )
end
end
每次调用@framework.response.cookies.set
时,它都会将Cookie数据推送到Framework::Response::Cookies
类@cookies
变量。
在提供回复之前,致电Framework::Response::Cookies.commit
使用Rack::Utils
提交Cookie。