I have a Ruby on Rails 4.2 multi-tenant application where I want each tenant to use it's own session cookie and cookie options. I tried different approaches but I can't get every detail right.
To add more context, tenant is selected from the host url in the request, in a Middleware, and set to a thread variable I can access down the stack. Let's call that settings object as Settings.current_account
.
Option 1: middleware:
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
and then in an initializer
Rails.application.config.session_store :cookie_store, key: 'bla',
expire_after: 1_209_600
Result: this will allow me to set expire_after
, but not the cookie name, that will remain bla
.
Option 2: custom cookie store
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
and then in an initializer:
Rails.application.config.session_store :account_cookie_store, key: 'bla',
expire_after: 1_209_600
But then it seems like the AccountCookieStore
instance is loaded BEFORE the call gets to the middleware were Settings.current_account
, hence no values can be fetched from the request and used to create the cookie.
Option 3: after_filter in ApplicationController
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
This just does not work.
What am I missing? Any ideas on how can I get this done?
same_site
supports getting a proc --:same_site => proc { |request| :lax }
– Feminize