为什么Rails在数据库中存储的session_id中使用前缀2::?

问题描述 投票:0回答:1

我正在开发一个使用 ActiveRecord::SessionStore 进行会话管理的 Rails 应用程序。在调试时,我注意到有关 session_id 的一个有趣的行为。这是我发现的:

  1. 用户cookie中的session_id如下所示:

    a5ef128d435c9c14f86450b0860d424

  2. 但是,在数据库(sessions 表)中,session_id 以哈希格式存储,带有前缀:

    2::3d05cf25eccf392f19e0049fa0f302a7bd4575a3b3daea9a2cde3173f723f7a0

我知道 2:: 之后的部分是 cookie 值 (session_id) 的 SHA-256 哈希值,但我对前缀 (2::):

很好奇
  • 2:: 是否表示会话加密的特定版本或 哈希机制?
  • 此行为是否记录在 Rails 或 ActiveRecord::SessionStore 宝石?

这是我尝试在代码中检索会话的方法:

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:: 更改,我的代码将会中断。

任何见解或文档指示将不胜感激!

ruby-on-rails activerecord
1个回答
0
投票

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就无法恢复,这是不可行的。

我认为最好在控制器的上下文中使用“会话”方法,否则使用忽略此标识符但可能存在问题的数据库检索。

© www.soinside.com 2019 - 2024. All rights reserved.