ruby-on-railssessionredisdevisewarden

How/Where does Devise/Warden generate the cache key used to store a session in Redis?


In my Rails application using Devise and Redis, I can call these things and get a session's ID:

# app/controllers/some_controller.rb

session.id
session[:session_id]
cookies['session_cookie']

The value returned for all of the above matches, and - as an example - let's say it's aaaabbbbccccdddd1111222233334444.

While that is happening in the app, I can run the console and get the cache key for the session:

# in the Rails console

redis = Redis.new
redis.keys

What shows up there looks nothing like the ID from before. It's something more like _session_id::2::984375urehgiuhfhe754w9873987e98trieydfijdoewsdjfh948570398408esf.

The question(s) is(are):

  1. How/When/Where does Devise (or is it Warden?) generate the cache key?
  2. How is the cache key related to the Session ID?
  3. Is there a way for a Rails controller to access or programmatically arrive at the session's corresponding cache key?

Solution

  • Thanks to Max's comment above, I dove into ActionDispatch::Session::CacheStore's code and understood that a session's id is actually not just a string, but an object passed around as sid inside that code. The object carries both a public_id (which is the string returned) and a private_id (which looks more related to what I see in Redis).

    Based on my original example:

    session.id
    # 'aaaabbbbccccdddd1111222233334444'
    
    session.id.public_id
    # 'aaaabbbbccccdddd1111222233334444'
    
    session.id.private_id
    # '2::984375urehgiuhfhe754w9873987e98trieydfijdoewsdjfh948570398408esf'
    
    # and in the console:
    redis = Redis.new
    redis.keys
    # ['_session_id::2::984375urehgiuhfhe754w9873987e98trieydfijdoewsdjfh948570398408esf']
    

    Seeing the private_id makes the Redis key far less mysterious.

    To get there precisely, I called something like session.instance_variable_get('@by').send(:cache_key, session.id.private), where @by is some kind of CacheStore-related instance and cache_key is the private method that generates the key used to interface with Redis.