将Rails会话存储在Redis中

8

Rails的默认会话存储方式是cookie_store,这意味着会话会被存储在客户端(如果我有误请纠正)。

我希望更改此默认行为,以便将会话存储到Redis数据库中。网上发现的文章建议设置缓存存储使用redis_cache_store,然后对于会话存储,使用cache_store

据我所知,这意味着缓存和会话都将使用同一数据库实例。但我想要的是,会话和缓存都使用不同的Redis实例,这样它们可以分别进行配置。

我尝试创建一个名为config/initializers/session_store.rb的初始化文件,并添加以下内容:

Rails.application.config.session_store :redis_cache_store, key: '_my_app_session'

但这不起作用。它会给我以下错误:

/application/configuration.rb:324:in `const_get': 未初始化常量ActionDispatch::Session::RedisCacheStore (NameError)

我还发现了这个gem:https://github.com/redis-store/redis-store,但我不确定使用这个gem是否有问题,因为Rails已经内置了Redis缓存库(https://github.com/rails/rails/pull/31134)。


查看Gemfile/Gemfile.lock文件,确保你的redis-cache-store被正确加载。 - Малъ Скрылевъ
2个回答

1
redis-rails中所解释的那样,Rails从5.2版本开始默认提供了Redis缓存存储。
建议使用这个存储来进行缓存(片段缓存)。
对于会话,您仍然可以使用redis-actionpack提供的会话存储,它是redis-rails的一部分,也可以单独使用。
因此,您应该在Gemfile中定义如下内容:
gem 'redis'
gem 'hiredis' # optional
gem 'redis-actionpack'

在你的环境中,为Rails 6及以上版本定义缓存和会话存储(参见Rails Guide和gem redis-rails)(感谢@daveomcd)。
# config/environments/production.rb
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }
config.session_store :redis_store,
  servers: ["#{ENV['REDIS_URL']}/session"],
  expire_after: 90.minutes,
  key: "_#{Rails.application.class.module_parent_name.downcase}_session",
  secure: true

现在你正在使用Rails的缓存存储和redis-rails的会话存储。
会话可以进行命名空间划分,或者可以存在于不同的redis实例中。

Rails 6之前:

在Rails 6之前,应用程序的名称(用于键)是通过推导得出的

Rails.application.class.parent_name.downcase

现在应该是 Rails.application.class.module_parent_name.downcase - daveomcd

-4

redis_cache_store 是一个缓存存储,你不能直接将其用作会话存储。你需要将 redis_cache_store 作为默认的 cache_store,然后你才能将 cache_store 用于你的 session_store。就像这样:

在你的 config/application.rb 中(阅读 this 以了解原因)

config.cache_store = :redis_cache_store, options

然后在你的config/initializers/session_store.rb文件中

Rails.application.config.session_store = :cache_store, key: '_app_session_key'

还有其他选项可以在不修改cache_store的情况下完成此操作,例如redis-storeredis-session-store


1
如果您查看第二段,您会发现这是我想要避免的模式。我需要将它们完全分开。目前我正在使用redis-store gem。但对我来说并没有太多意义,因为Rails已经有了内置的redis实现。 - user15245135
1
目前无法为会话和缓存存储使用不同的Redis数据库。在此提供了更详细的解释:https://stackoverflow.com/questions/51717865/using-different-redis-stores-for-session-and-caching-in-rails-5 - Monith Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接