在 Rails 3 中设置会话超时

发布于 2024-11-04 14:48:40 字数 512 浏览 0 评论 0原文

这看起来很简单:我试图让 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 中的情况已经发生了变化。

有人可以帮我吗?

This seems simple: I am trying to get my rails Active Record session to timeout after 2 minutes. So after two minutes I want my users to have to re-login.

I'm just running rails server (i.e. WebBrick) on my local dev machine.

I know this is something to do with the following code in config/initalizers/session_store.rb, but I don't think I have quite nailed it:

CodedOn::Application.config.session_store :active_record_store

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

This doesn't seem to work, or at least my session doesn't appear to timeout. I can't find much about the Rails 3 way to do this as I know things have changed from Rails 2.x.

Can some one help me out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

幽蝶幻影 2024-11-11 14:48:40

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

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

I think you will have to do this manually since the active record store does not implement the expire_after option. So within your (I assume) before filter, you should do this:

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

Obviously, this is not complete, but it should give you the basic idea.

UPDATE:

It seems that the functionality IS present in rails since version 2.3. I found the relevant code here. This is AbstractStore which should serve as base class for all derived ones. So, as dadooda suggests, the following should work:

Some::Application.config.session_store :active_record_store, {
  expire_after: 24.hours,
}
旧伤慢歌 2024-11-11 14:48:40

我以简单的方式做到了这一点,您可以尝试以下操作:

在您的 config/initializers/session_store.rb 中,只需执行以下操作:

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

这对我来说效果很好,希望对您也有用。

I did this in simple way you can try this:

In your config/initializers/session_store.rb just do this:

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

This is working for me finely, hope works for you also.

我也只是我 2024-11-11 14:48:40

你必须手动完成。下面是为 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#会话过期

You have to do it manually. Here's an example of creating a class method for ActiveRecord sessions. You can use Rufus-Scheduler and/or DelayedJob to regularly call this.

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

More background on why it's important: http://guides.rubyonrails.org/security.html#session-expiry

弃爱 2024-11-11 14:48:40

莫施 说:

我认为您必须手动执行此操作,因为活动记录存储未实现 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 功能,到目前为止似乎有效。

mosch says:

I think you will have to do this manually since the active record store does not implement the expire_after option.

It seems it's no longer this way. :expire_after worked for me in Rails 3.2.11:

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

The cookie auto-prolongs after every request towards the app. The session persists through browser exits.

I did the above trick to "globalize" the session across domain for a simple SSO functionality, seems to work so far.

对你再特殊 2024-11-11 14:48:40

到期时间。

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

The expiration time.

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
动听の歌 2024-11-11 14:48:40

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

  def timeout_in
    2.minutes
  end

Just add timeout_in method in your model and it should do the trick:

  def timeout_in
    2.minutes
  end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文