1

默认情况下,rails 使用 cookie 存储会话信息。我遵循的教程说这是最好的方法,而且速度非常快,而且它都被加密了。但是当我对 cookie 内容进行 base64 解码时,我可以在那里看到我的会话信息。它混入了很多乱码字符中,但它就在那里。

我在这里想念什么?

Rails 不是使用那个秘密令牌来加密 cookie 中的信息吗?我怎样才能做到这一点?

4

1 回答 1

3

Rails 使用秘密令牌对会话进行签名。原始数据仍然存在,但更改它会导致它不再匹配签名,Rails 将拒绝它。cookie 字符串看起来像session_data--signature,会话数据是 base64 编码的编组对象,签名是HMAC(session string, secret token)

会话数据的一般假设是它不是秘密的(因为它通常应该只包含一些东西,比如 CSRF 令牌和用户 ID),但它不应该由用户更改。cookie 签名实现了这一点。

如果您需要实际加密数据以使用户永远看不到它,您可以使用 OpenSSL 对称加密之类的方法来执行此操作,或者您可以切换到非 cookie 数据存储。

这是我自己的应用程序 cookie 商店的变体;我还没有测试过,但理论上这应该会为你生成实际加密的 cookie。请注意,这将明显比默认的 cookie 存储慢,并且根据其运行时间,可能是 DOS 向量。此外,加密数据将比未加密数据更长,并且会话 cookie 有 4kb 的限制,因此如果您在会话中存储大量数据,这可能会导致您超出该限制。

# Define our message encryptor
module ActiveSupport
  class EncryptedMessageVerifier < MessageVerifier
    def verify(message)
      Marshal.load cryptor.decrypt_and_verify(message)
    end

    def generate(value)
      cryptor.encrypt_and_sign Marshal.dump(value)
    end

    def cryptor
      ActiveSupport::MessageEncryptor.new(@secret)
    end
  end
end

# And then patch it into SignedCookieJar
class ActionDispatch::Cookies::SignedCookieJar
  def initialize(parent_jar, secret)
    ensure_secret_secure(secret)
    @parent_jar = parent_jar
    @verifier   = ActiveSupport::EncryptedMessageVerifier.new(secret)
  end
end
于 2012-11-30T21:02:38.380 回答