Store Rails session using Redis
Asked Answered
F

2

10

The default session store for Rails is cookie_store. This makes the session be stored on the client side (correct me if I am wrong).

I want to change this default behavior, so that I can store the sessions into Redis database. The posts/articles I found on the Internet, suggests setup a caching store to use redis_cache_store and then for the session_store, to use cache_store.

As I got it, this means that, both caching and sessions will be using the same database (Instance). I don't want that. I want both sessions and cache to use different instances of Redis, so they can be configured accordingly.

I tried to create an initializer file config/initializers/session_store.rb with the following content:

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

But this does not work. It gives me the following error:

/application/configuration.rb:324:in `const_get': uninitialized constant ActionDispatch::Session::RedisCacheStore (NameError)

I also found this gem https://github.com/redis-store/redis-store but I am not sure how problematic using this gem can be, since Rails already has a built-in Redis cache store (https://github.com/rails/rails/pull/31134)

Faubourg answered 19/2, 2021 at 20:13 Comment(1)
look into Gemfile/Gemfile.lock to make sure that your redis-cache-store is pickupWintertime
G
2

As explained in redis-rails, Rails has a redis cache store out of the box starting with Rails 5.2.

The advise is to use this store for caching (fragment cache).

For sessions, you can still use the session store provided by redis-actionpack which is a part of redis-rails and can be used on its own.

So you should define in your Gemfile:

gem 'redis'
gem 'hiredis' # optional
gem 'redis-actionpack'

In your environment, define cache and session store (see Rails Guide and gem redis-rails) for Rail 6 and up (thanks to @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

Now your using the cache store of Rails and the session store of redis-rails.
The sessions are namespaced or can be in a different redis instance.

Rails before 6:

before Rails 6 the name of the application (used in key) was derived by

Rails.application.class.parent_name.downcase
Gadolinium answered 29/12, 2022 at 14:58 Comment(1)
should now be Rails.application.class.module_parent_name.downcasePolecat
C
-4

redis_cache_store is a cache store, you cannot directly use it as a session store. You will have to use redis_cache_store as your default cache_store and then you can use the cache_store for your session_store. Something like this

In your config/application.rb (Read this to know why here)

config.cache_store = :redis_cache_store, options

and then in your config/initializers/session_store.rb

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

There are other options to do this without modifying cache_store as well such as redis-store and redis-session-store

Calderon answered 20/2, 2021 at 6:53 Comment(2)
If you look to the second paragraph, you will see that this is the pattern I want to avoid. I need to have them completely separated. Rigth now I am using redis-store gem. But make not to much sense to me since rails already have a build-in redis implementationFaubourg
Using different redis db for session and cache store is not possible for now. More detailed explanation has been provided here #51718365Calderon

© 2022 - 2024 — McMap. All rights reserved.