我有一个 Ruby on Rails 4.2 多租户应用程序,我希望每个租户使用它自己的会话 cookie 和 cookie 选项。我尝试了不同的方法,但我无法正确处理每个细节。
要添加更多上下文,从请求中的主机 url 中选择租户,在中间件中,并将其设置为我可以访问堆栈的线程变量。让我们将该设置对象称为Settings.current_account
.
选项 1:中间件:
class AccountableSessionCookies
def initialize(app)
@app = app
end
# @param [Hash] The Rack environment.
def call(env)
dup.call!(env)
end
# @param env [Hash] The Rack environment.
def call!(env)
env['rack.session.options'][:key] = Settings.current_account.session_key
env['rack.session.options'][:expire_after] = Settings.current_account.session_expiration
@app.call(env)
end
end
然后在初始化程序中
Rails.application.config.session_store :cookie_store, key: 'bla',
expire_after: 1_209_600
结果:这将允许我设置expire_after
保留的 cookie 名称,但不能设置 cookie 名称bla
。
选项 2:自定义 cookie 存储
module ActionDispatch
module Session
class AccountCookieStore < CookieStore
def initialize(app, options={})
super(app, options.merge!(key: Settings.current_account.session_key),
expire_after: Settings.current_account.session_expiration)))
end
end
end
end
然后在初始化程序中:
Rails.application.config.session_store :account_cookie_store, key: 'bla',
expire_after: 1_209_600
但是看起来AccountCookieStore
实例是在调用到达中间件之前加载的Settings.current_account
,因此无法从请求中获取任何值并用于创建 cookie。
选项 3:ApplicationController 中的 after_filter
after_filter :short_session
def short_session
request.session_options = request.session_options.dup
request.session_options[:expire_after] = 100.days.to_i
request.session_options[:key] = 'mynewkey'
request.session_options.freeze
end
这只是行不通。
我错过了什么?关于如何完成这项工作的任何想法?