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):
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.