我正在开发一个使用 ActiveRecord::SessionStore 进行会话管理的 Rails 应用程序。在调试时,我注意到有关 session_id 的一个有趣行为。以下是我发现的内容:
用户 cookie 中的 session_id 如下所示:
a5ef128d435c9c14f86450b0860d424
但是,在数据库(会话表)中,session_id 以哈希格式存储,并带有前缀:
2::3d05cf25eccf392f19e0049fa0f302a7bd4575a3b3daea9a2cde3173f723f7a0
我理解 2:: 后面的部分是 cookie 值 (session_id) 的 SHA-256 哈希值,但我对前缀 (2::) 很好奇:
- 2:: 是否表示会话加密或散列机制的特定版本?
- 这种行为是否在 Rails 或 ActiveRecord::SessionStore gem 的某个地方有记录?
以下是我尝试在代码中检索会话的方法:
current_user_id = lambda { |request|
session_id = request.cookie_jar["_session_id"]
return unless session_id.present?
encrypted_session_id = "2::#{Digest::SHA256.hexdigest(session_id)}"
session = ActiveRecord::SessionStore::Session.find_by(session_id: encrypted_session_id)
session&.data&.fetch('user_id', nil)
}
这按预期工作,但我有一个担心:如果前缀 2:: 发生变化,我的代码就会中断。
如能提供任何见解或对文档的指引,我们将不胜感激!
session_id 前面的前缀恰好来自 Rack::Session(参见https://github.com/rack/rack-session/blob/498bfdf0757e288aa2cf949044892882628c0a67/lib/rack/session/abstract/id.rb#L31)他们在其前面添加了一个版本 ID,可能是为了管理与散列机制的向后兼容性,正如您可能已经猜到的那样。
因此前缀可能会改变,它被定义为,
Rack::Session::SessionId::ID_VERSION
因此您可以用以下代码替换它:但是如果id的版本发生变化,旧的会话就无法恢复,这是不可行的。
我认为最好在控制器上下文中使用“会话”方法,否则使用忽略此标识符的数据库检索但可能出现问题。