Devise/Warden 如何/在哪里生成用于在 Redis 中存储会话的缓存密钥?

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

提问人:vivipoit 提问时间:10/23/2023 更新时间:10/30/2023 访问量:39

问:

在我使用 Devise 和 Redis 的 Rails 应用程序中,我可以调用这些东西并获取会话的 ID:

# app/controllers/some_controller.rb

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

上述所有匹配项返回的值,例如,假设它是 。aaaabbbbccccdddd1111222233334444

当这种情况在应用程序中发生时,我可以运行控制台并获取会话的缓存密钥:

# in the Rails console

redis = Redis.new
redis.keys

那里显示的内容看起来与之前的 ID 完全不同。它更像是._session_id::2::984375urehgiuhfhe754w9873987e98trieydfijdoewsdjfh948570398408esf

问题是:

  1. Devise(或者是Warden?)如何/何时/何地生成缓存密钥?
  2. 缓存键与会话 ID 有何关系?
  3. 有没有办法让 Rails 控制器访问或以编程方式到达会话的相应缓存键?
Ruby-On-Rails 会话 Redis 设计 Warden

评论

1赞 max 10/23/2023
它既不是Devise也不是Warden。它是 Rails 自己的会话存储中间件。典狱长维基有一个很好的概述。然后你要问 3 个不同的问题,范围非常广泛。生成缓存键由 ActionDispatch::Session::CacheStore 完成,它与存储在 cookie 中的会话标识符相同。
0赞 max 10/23/2023
您可以使用获取会话 ID,但您永远不需要。session.id
0赞 vivipoit 10/28/2023
谢谢你的评论!它帮助我了解到,即使返回一个字符串,返回的项目实际上也是一个响应(返回的字符串)和(类似于我在调用时看到的东西)的对象。结果是,我能够调用 的方法并准确地得到我想要的东西!🥳 再次感谢!我将发布它作为问题的答案。session.idsidpublic_idprivate_idRedis.new.keysCacheStorecache_keysession.id.private_id

答:

1赞 vivipoit 10/28/2023 #1

感谢 Max 在上面的评论,我深入研究了 ActionDispatch::Session::CacheStore 的代码,并了解到会话的 id 实际上不仅仅是一个字符串,而是一个在该代码中传递的对象。该对象同时携带 a(这是返回的字符串)和 a(看起来与我在 Redis 中看到的内容更相关)。sidpublic_idprivate_id

基于我的原始示例:

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']

看到这一点,Redis 密钥就不那么神秘了。private_id

为了准确地到达那里,我调用了类似 的东西,其中是某种与 CacheStore 相关的实例,并且是生成用于与 Redis 交互的密钥的私有方法。session.instance_variable_get('@by').send(:cache_key, session.id.private)@bycache_key