在Rails 3中设置会话超时

时间:2011-05-02 18:35:21

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

这看起来很简单:我试图让我的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已经改变了。

有人可以帮助我吗?

6 个答案:

答案 0 :(得分:46)

我认为您必须手动执行此操作,因为活动记录存储未实现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开始,似乎功能IS存在于rails中。我找到了相关代码here。这是AbstractStore,它应该作为所有派生类的基类。所以,正如dadooda建议的那样,以下内容应该有效:

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

答案 1 :(得分:40)

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

config/initializers/session_store.rb中执行此操作:

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

这对我很有帮助,希望也适合你。

答案 2 :(得分:4)

你必须手动完成。这是为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

答案 3 :(得分:4)

莫斯奇说:

  

我认为您必须手动执行此操作,因为活动记录存储未实现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功能,我做了上述“全局化”跨域会话的技巧,到目前为止似乎有效。

答案 4 :(得分:2)

到期时间。

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

答案 5 :(得分:-5)

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

  def timeout_in
    2.minutes
  end