ruby-on-railssessionruby-on-rails-5.2session-storeredis-rails

Keeping Existing Sessions When Upgrading to Rails 5.2 (with Redis Session Store)


I have recently finished a big upgrade of a Rails application. I took the App incrementally from Rails 4.2.8 to Rails 5.2.3. Everything has gone smoothly, all our automated tests are passing, and we've begun user acceptance testing.

So far the only issue that has been found is that logged in users are being signed out by this upgrade. We previously had the redis-rails gem (version 4.0.0) installed to enable using Redis for our session_store and now we're using the built-in Redis store that comes with Rails 5.2.

I have our configuration set up to use the same Redis connection and the same session_store key value as before, and I can't figure out why sessions are still being reset. It seems like perhaps redis-rails 4.0.0 was not properly setting the session_store key value?

Has anyone else dealt with this and successfully retained existing sessions when upgrading from redis-rails to Rails 5.2?

Edit: Other possibly-related gems that have been updated include ruby 2.3.4 => 2.5.5, devise 4.0.3 => 4.6.2, & redis 3.2.2 => 4.1.2


Solution

  • I have figured this out! I thought that the key parameter for the session_store config was supposed to be setting the Redis Key value. This parameter is actually used for the users browser cookie key. The upgrades I made did add a new Redis key to the session store values, but it doesn't look like there are any parameters to change or remove this new Redis key.

    My solution was to use a script to rename all of my Redis session keys to match the new format (I use 'namespace' as the Redis cache store namespace):

    redis-cli --scan --pattern "namespace:*"  | \
    awk '/^/ {new_key=$1;gsub(/namespace:/,"namespace:_session_id:", new_key); printf "*3\r\n$6\r\nrename\r\n$" length($1) "\r\n" $1 "\r\n$" length(new_key) "\r\n"  new_key "\r\n";}'  | \
    redis-cli --pipe
    

    The final relevant config is:

    config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'], namespace: 'namespace' }
    config.session_store :cache_store, key: '_mysite_session'
    

    The downside to this is that it also invalidates and incorrectly renames all of the other Redis cache objects since the session stores did not have a key to identify them before.