All good things come to an end: At least that’s how it’s supposed to work.
SessionExpirable is an enhanced version of Devise[https://github.com/plataformatec/devise]‘s timeoutable
module that ensures that no session is allowed to last forever.
Like Devise timeoutable
, SessionExpirable adds a timestamp to sessions indicating the last time that the session was used, and checks these timestamps when a session is used to sign a user in. A configurable timeout_in
option controls how long inactive sessions are considered valid.
When timeoutable
reads a session that does not contain a timestamp, timestamp validation is bypassed: A session without a timestamp will never be considered as having timed out.
In order to prevent the abuse of non-expiring sessions, SessionExpirable treats sessions without timestamps as having already expired.
Another difference is that in the case of a timeout, timeoutable
prevents other authentication strategies from being tried, although it has custom logic to allow Devise rememberable
to work in spite of a timed-out session.
SessionExpirable does not allow a timed-out session to interfere with any authentication strategies that are configured. One consequence is that SessionExpirable does not support invalidation of authentication tokens from the Devise token_authenticatable
module when a request with a valid authentication token is accompanied by an expired session.
One final difference is that SessionExpirable does not invoke the Devise FailureApp for requests that do not require authentication.
Add devise_session_expirable
to your Gemfile:
gem 'devise_session_expirable'
Include :session_expirable
in your devise user model declaration:
class User < ActiveRecord::Base devise :database_authenticatable, :session_expirable # ... end
Then update the Devise initializer:
Devise.setup do |config| # ... config.timeout_in = 15.minutes config.default_last_request_at = Time.parse('2013-02-16T00:00:00Z') # ... end
The default_last_request_at
option is intended to enable a less disruptive migration if sessions without timestamps have already been issued. The configured value will be used in place of the timestamp for sessions which don’t have one.
If default_last_request_at
is configured, it should be set to a fixed date/time, ideally matching the time of deployment. If set to a dynamic time (e.g. Time.now), the lifetime of sessions without timestamps will be extended every time Rails is initialized.
After the timeout_in
interval passes, any legacy sessions will have expired and default_last_request_at
can be unset.
As long as you reset your secret_token when configuring Devise timeoutable
to your rails application and avoid authenticating for actions which set devise.skip_trackable
in the rack environment, you will have eliminated at least two possible sources of non-expiring sessions.
This module was adapted from Devise’s timeoutable
module.
Thanks to the creators and maintainers of Devise and Warden for a truly extensible authentication library.
-
Fork the project.
-
Start a feature/bugfix branch.
-
Commit and push.
-
Make sure to add tests.
Copyright © 2013 Riley Lynch, Teleological Software, LLC. See LICENSE.txt for further details.