【问题标题】:Setting session timeout in Rails 3在 Rails 3 中设置会话超时
【发布时间】:2011-08-17 04:27:33
【问题描述】:

这看起来很简单:我试图让我的 rails Active Record 会话在 2 分钟后超时。因此,两分钟后,我希望我的用户必须重新登录。

我只是在我的本地开发机器上运行 rails server(即 WebBrick)。

我知道这与config/initalizers/session_store.rb 中的以下代码有关,但我认为我没有完全确定:

CodedOn::Application.config.session_store :active_record_store

CodedOn::Application.configure do
    config.action_controller.session = {:expire_after => 2.minutes}
end

这似乎不起作用,或者至少我的会话似乎没有超时。我找不到太多关于 Rails 3 方法的信息,因为我知道 Rails 2.x 发生了变化。

有人可以帮我吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 session activerecord


    【解决方案1】:

    我认为您必须手动执行此操作,因为活动记录存储未实现 expire_after 选项。所以在你的(我假设)过滤之前,你应该这样做:

    def authenticate
      if session[:logged_in]
        reset_session if session[:last_seen] < 2.minutes.ago
        session[:last_seen] = Time.now
      else
        ... authenticate
        session[:last_seen] = Time.now
      end
    end
    

    显然,这并不完整,但它应该给你基本的想法。

    更新

    似乎该功能自 2.3 版起就存在于 rails 中。我找到了相关代码here。这是 AbstractStore,它应该作为所有派生类的基类。因此,正如 dadooda 所建议的那样,以下应该可行:

    Some::Application.config.session_store :active_record_store, {
      expire_after: 24.hours,
    }
    

    【讨论】:

    • 这里的一个问题是它是如何工作的......就像在最初创建会话时调用before_filter - 即当用户第一次通过身份验证时,session[:last_seen] 是如何工作的又叫了?如果它是一个身份验证 before_filter,它不是只调用一次 - 在身份验证时?我想我想弄清楚的是,一旦创建了会话并且用户登录了,我如何检查session[:last_seen],以便如果它超过X 的分钟数,它会迫使他们重新-登录,在会话的初始创建时不这样做。希望这是有道理的
    • 我希望我得到了你的问题:HTTP 是无状态的。因此,网络服务器看不到任何两个请求之间的任何关系。但是有些用例需要这种关系(例如身份验证)。在 Rails 中,会话哈希提供了这一点。但是控制器确实必须读取每个请求的会话哈希,以便识别以前经过身份验证的用户。因此,在每个请求之前都会调用 'authenticate'-before 过滤器。我希望这会有所帮助。
    • 鉴于我是从头开始编写身份验证的,假设我在每个控制器上明确调用 before_filter,或者我必须在每个控制器上传递 filter_resource_access,您的答案是否有效?控制器以强制它这样做?我知道如果我使用 devise 或其他一些身份验证 gem,它会为我处理这些东西 - 但鉴于我是从头开始编写的,这就是我问这些问题的原因。
    • 或者rails会在每次控制器请求之前自动调用application_controller中的所有before_filters
    • @marcamillion:这是因为按照惯例,您的控制器都继承自 ApplicationController(例如 class PostsController &lt; ApplicationController),因此它们继承了 before_filter 声明。
    【解决方案2】:

    我以简单的方式做到了这一点,你可以试试这个:

    在你的config/initializers/session_store.rb 中这样做:

    Yourapp::Application.config.session_store :cookie_store, 
                                                 :key => "_yourapp_session",
                                                 :expire_after => 2.minutes
    

    这对我很有效,希望对你也有效。

    【讨论】:

    • 也适用于 Rails 5.0.0。
    【解决方案3】:

    您必须手动完成。下面是为 ActiveRecord 会话创建类方法的示例。您可以使用 Rufus-Scheduler 和/或 DelayedJob 定期调用它。

    class Session < ActiveRecord::Base
      def self.sweep(time = 1.hour)
        if time.is_a?(String)
          time = time.split.inject { |count, unit| count.to_i.send(unit) }
        end
    
        delete_all "updated_at < '#{time.ago.to_s(:db)}' OR created_at < '#{2.days.ago.to_s(:db)}'"
      end
    end
    

    更多关于它为何重要的背景信息:http://guides.rubyonrails.org/security.html#session-expiry

    【讨论】:

      【解决方案4】:

      mosch 说:

      我认为您必须手动执行此操作,因为活动记录存储未实现 expire_after 选项。

      似乎不再是这样了。 :expire_after 在 Rails 3.2.11 中为我工作:

      Some::Application.config.session_store :active_record_store, {
        key: "some_session_id",
        domain: ".isp.com",
        expire_after: 24.hours,
      }
      

      Cookie 会在每次向应用发出请求后自动延长。会话通过浏览器退出持续存在。

      我使用上述技巧将跨域的会话“全球化”以实现简单的 SSO 功能,目前看来可行。

      【讨论】:

        【解决方案5】:

        到期时间。

        MAX_SESSION_TIME = 60 * 60
        
        before_filter :prepare_session
        
        def prepare_session
        
           if !session[:expiry_time].nil? and session[:expiry_time] < Time.now
              # Session has expired. Clear the current session.
              reset_session
           end
        
           # Assign a new expiry time, whether the session has expired or not.
           session[:expiry_time] = MAX_SESSION_TIME.seconds.from_now
           return true
        end
        

        【讨论】:

          【解决方案6】:

          只需在模型中添加 timeout_in 方法,它就可以解决问题:

          def timeout_in 2分钟 结尾

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-11
            • 2012-08-18
            • 1970-01-01
            相关资源
            最近更新 更多