Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store Rails session using Redis

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)


1 Answers

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
like image 111
Martin M Avatar answered Apr 13 '26 20:04

Martin M