3

我有一个 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

这只是行不通。

我错过了什么?关于如何完成这项工作的任何想法?

4

0 回答 0