【问题标题】:Access Session version number in rails在 rails 中访问 Session 版本号
【发布时间】:2020-03-13 18:57:54
【问题描述】:

我知道一旦访问会话,rails 就会分配会话 ID。我听说如果修改了会话,rails 在会话上会有一个版本标记。我找不到确切的参考,此外,我正在寻找一种方法来访问会话的版本号? 我知道我在这里含糊不清,但是如果能指出我正确的方向,我将不胜感激。 我知道可以访问会话 ID,但我更具体地希望访问给定会话 ID 的版本号,以跟踪它被更改的次数。

【问题讨论】:

  • 您从哪里听说过会话数据的版本控制?会话数据是一次性的,一直在变化。如果您存储会话数据,您可以添加自己的版本控制,但我从未听说过 Rails 版本控制会话数据。

标签: ruby-on-rails session


【解决方案1】:

我知道一旦访问会话,会话 ID 由 铁轨。听说如果修改了一个session,rails有一个版本 在会话上盖章。

通过阅读ActionDispatch::Session::CookieStore的源代码可以很容易地验证这个说法是错误的。

# frozen_string_literal: true
require "active_support/core_ext/hash/keys"
require "action_dispatch/middleware/session/abstract_store"
require "rack/session/cookie"

module ActionDispatch
  module Session
    # ... comments truncated for readibility
    class CookieStore < AbstractStore
      def initialize(app, options = {})
        super(app, options.merge!(cookie_only: true))
      end

      def delete_session(req, session_id, options)
        new_sid = generate_sid unless options[:drop]
        # Reset hash and Assign the new session id
        req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid } : {})
        new_sid
      end

      def load_session(req)
        stale_session_check! do
          data = unpacked_cookie_data(req)
          data = persistent_session_id!(data)
          [data["session_id"], data]
        end
      end

      private

        def extract_session_id(req)
          stale_session_check! do
            unpacked_cookie_data(req)["session_id"]
          end
        end

        def unpacked_cookie_data(req)
          req.fetch_header("action_dispatch.request.unsigned_session_cookie") do |k|
            v = stale_session_check! do
              if data = get_cookie(req)
                data.stringify_keys!
              end
              data || {}
            end
            req.set_header k, v
          end
        end

        def persistent_session_id!(data, sid = nil)
          data ||= {}
          data["session_id"] ||= sid || generate_sid
          data
        end

        def write_session(req, sid, session_data, options)
          session_data["session_id"] = sid
          session_data
        end

        def set_cookie(request, session_id, cookie)
          cookie_jar(request)[@key] = cookie
        end

        def get_cookie(req)
          cookie_jar(req)[@key]
        end

        def cookie_jar(request)
          request.cookie_jar.signed_or_encrypted
        end
    end
  end
end

如您所见,persistent_session_id! 会覆盖现有的会话 ID cookie。它不跟踪以前的 sid。对于会话、memcached (dalli) 和 ActiveRecord 等其他存储,似乎并没有明显删除 sid,但没有您想象的那种“版本控制”api。

如果您想拥有此功能,您可以将中间件堆栈中的 ActionDispatch::Session::CookieStore(或您正在使用的任何存储)与您自己的会话中间件交换。

对于您正在做的任何事情,可能有一个更简单的解决方案,但如果它是常见的东西,例如存储用户登录次数(将其存储在数据库中)或页面浏览量(使用谷歌分析或数据库)或您有什么.此外,如果您正在做的任何事情都需要版本化 - 它真的应该首先在会话中吗?

【讨论】:

  • 啊,我当时的印象是错误的,感谢您纠正我并提供替代解决方案。因此,通过版本控制,我只想跟踪会话是否已被修改。我曾在其他博客中阅读过关于按照您的建议更换中间件堆栈的内容,但这些博客已经有 10 年的历史了,所以,我期待 Rails 已经改变(添加了这个)。
  • 为什么要加?这不值得增加复杂性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-24
相关资源
最近更新 更多