如何在Rails应用程序中使用activerecord activerecord-session_store使用cookie值在数据库中查找会话记录

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

我有一个 Rails 应用程序,它使用 Devise 和 activerecord-session_store gem 以及简约的设置(没有超出默认值)。

我正在尝试使用存储在cookie中的值来手动查找activerecord-session_store使用的

sessions
表中相应的会话记录。

问题是我从 cookie 获取的会话值似乎没有“按原样”存储在数据库中,因此我不能简单地执行 find_by 来查找它匹配的记录。

或者换句话说:

cookie 值如下所示: a5a879b4f923d2eea7707cf8ce28cd80

这就是

session_id
表中的
sessions
的样子: 2::801e4371783f192b4ee95be9def08bf17daaa1ebeed589dbdfeeb8742e2dd9f6

sessions
表中的值似乎以某种方式加密,我找不到有关如何匹配两者的信息。

值得指出的是,该应用程序工作正常,因此它以某种方式在内部进行匹配。我正在尝试为不同的用例匹配 session_id。

我尝试使用

find_by_session_id
公开的
ActiveRecord::SessionStore::Session
方法,希望它能进行一些转换并神奇地找到正确的会话,但它似乎只是活动记录中的标准 find_by ,由于字符串值不同,因此不起作用.

我的猜测是,我需要以某种方式将来自 cookie 的值转换为保存在 session_id 列中的格式数据,然后才执行 find_by 但我不知道如何。

您知道如何使用 cookie 值找到正确的会话吗?谢谢

ruby-on-rails activerecord
2个回答
4
投票

虽然我无法提供有关其工作方式和原因的详细信息,但我找到了解决方案:

首先,需要根据 cookie 值生成一个 private_session_id,然后才能调用

find_by_session_id

类似这样的:

private_session_id = Rack::Session::SessionId.new(COOKIE_VALUE).private_id
ActiveRecord::SessionStore::Session.find_by_session_id(private_session_id)


0
投票

只是想为之前的答案做出更多贡献,因为我自己对这个问题很好奇。

有关更多详细信息,请访问 activerecord-session_store gem 源代码,您可以在其中找到处理我们正在讨论的内容的

Rack::Session::SessionId
类。

要使其工作,需要在对象初始化期间传递从 cookie 获取的

public_id
。在类中,有一个常量
ID_VERSION
设置为 2。

私有方法

hash_sid
采用字符串作为输入并返回64个字符的十六进制值:

def hash_sid(sid)
  Digest::SHA256.hexdigest(sid)
end

然后,有一个名为

private_id
的方法,它会为您提供一个与数据库记录中存储的
session_id
相匹配的字符串:

def private_id
  "#{ID_VERSION}::#{hash_sid(public_id)}"
end

您可以根据您的实现使用以下任一查询:

ActiveRecord::SessionStore::Session.find_by_session_id(private_id)

Session.find_by(session_id: private_id)
© www.soinside.com 2019 - 2024. All rights reserved.