Skip to content

Configure auto session timeout with devise gem

Zaim Ramlan edited this page Oct 14, 2016 · 3 revisions

Big thanks to @kales33 for writing a step-by-step configuration of this gem with devise gem. I'm simply re-writing this from his answer here onto this wiki to assist developers in the future who would like to use this gem in their rails app.

Let's get started yo!

Requirements

Tested and Working with

  • Ruby v2.3.1
  • Rails v4.2.6

Dependency

Configuration

  1. Follow the steps here in order to customize the Devise sessions controllers. Just for reference, my config/routes.rb file is set up in the following way:
Myapp::Application.routes.draw do
  devise_for :users, controllers: { sessions: "users/sessions" }

  devise_scope :user do
    match 'active'            => 'users/sessions#active',               via: :get  
    match 'timeout'           => 'users/sessions#timeout',              via: :get   
  end  
  
  #other routes
end
  1. In app/controllers/users/sessions_controller.rb, I have the following code:
class Users::SessionsController < Devise::SessionsController
  layout 'login' #specifies that the template app/views/layouts/login.html.erb should be used instead of app/views/layouts/application.html.erb for the login page

  #configure auto_session_timeout
  def active
    # this method comes from auto-session-timeout gem
    render_session_status

    # if your devise model is NOT named as `user`, use the code below
    # instead of the above code.
    # replace `user` in `current_user` with your devise model's name. (i.e. admin)
    
    # response.headers["Etag"] = ""  # clear etags to prevent caching
    # render text: !!current_user, status: 200
  end

  def timeout
    flash[:notice] = "Your session has timed out."
    # you may change this to any_desired_path
    redirect_to "/users/sign_in"
  end
end
  1. In app/controllers/application_controller.rb, I have the following code:
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :authenticate_user!
  auto_session_timeout 30.minutes

end
  • Note that we set the authentication token expiration time to be 30 minutes using auto_session_timeout.
    This replaces the Devise :timeoutable functionality.
  1. In my app, I have two layout templates.

4.1) Pages that the user sees when they are logged in: app/views/layouts/application.html.erb
4.2) The login screen: app/views/layouts/login.html.erb
In both of these files, I added the line below within the html <body> element:

<%= auto_session_timeout_js %>
  • This code will generate Javascript that checks the status of the authentication token every 60 seconds.
    (this time interval is configurable)

  • If the token has timed out, the Javascript code will call the timeout method in the app/controllers/users/sessions_controller.rb file.

  • Note that I have included this code on the app/views/layouts/login.html.erb page.

  • The reason for this is because if there is no activity on the login page for more than 30 minutes (or whatever the auto_session_timeout setting is in the application_controller.rb file), then the authentication token will expire, and the user will receive an Invalid Authentication Token error when trying to login.

  • Adding the code <%= auto_session_timeout_js %> will cause the login to be refreshed when the authentication token expires, thus preventing this error from occurring.

Clone this wiki locally