我正在开发一个使用 ActiveRecord::SessionStore 进行会话管理的 Rails 应用程序。在调试时,我注意到有关 session_id 的一个有趣的行为。这是我发现的:
用户cookie中的session_id如下所示:
a5ef128d435c9c14f86450b0860d424
但是,在数据库(sessions 表)中,session_id 以哈希格式存储,带有前缀:
2::3d05cf25eccf392f19e0049fa0f302a7bd4575a3b3daea9a2cde3173f723f7a0
我知道 2:: 之后的部分是 cookie 值 (session_id) 的 SHA-256 哈希值,但我对前缀 (2::):
很好奇这是我尝试在代码中检索会话的方法:
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
定义的,因此您可以将代码替换为:
encrypted_session_id = ‘#{Rack::Session::SessionId::ID_VERSION}::#{Digest::SHA256.hexdigest(session_id)}’
但是如果id的版本发生变化,旧的session就无法恢复,这是不可行的。
我认为最好在控制器的上下文中使用“会话”方法,否则使用忽略此标识符但可能存在问题的数据库检索。