Setting session timeout in Rails 3
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?
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,
}
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.
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
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.
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
Just add timeout_in method in your model and it should do the trick:
def timeout_in 2.minutes end
精彩评论