A user can only be signed in a single session at a time. This means if he logged in to computer A then afterwards he logged in to computer B, then computer A times out. The original question was solved in http://stackoverflow.com/questions/7068919/devise-limit-one-session-per-user-at-a-time

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery
 
  before_filter :authenticate_user!, :check_concurrent_session, :store_location
 
  ... 
  def check_concurrent_session
    if is_already_logged_in?
      sign_out_and_redirect(current_user)
    end
  end
 
  def is_already_logged_in?
    current_user && !(session[:token] == current_user.login_token)
  end
 
  def after_sign_out_path_for(resource)
    loggedout_path
  end
 
end

app/controllers/sessions_controller.rb

class SessionsController < Devise::SessionsController
 
  skip_before_filter :check_concurrent_session
 
  def create
    super
    set_login_token
  end
 
  private
  def set_login_token
    token = Devise.friendly_token
    session[:token] = token
    current_user.login_token = token
    current_user.save
  end
 
end

app/controllers/static_controller.rb

class StaticController < ApplicationController
  skip_before_filter :authenticate_user!
end

app/views/sessions/new.html.erb

<div id="application">
 
 <nav id="secondary">
    <ul>
      <li class="current"><%= link_to "Log In", new_user_session_path %></li>
      <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
        <li><%= link_to "Forgot Password", new_password_path(resource_name) %></li>
      <% end -%>
    </ul>
  </nav>
 
  <section id="content">
 
    <%= semantic_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
      <section>
        <%= f.input :username %>
      </section>
 
      <section>
        <%= f.input :password %>
      </section>
 
      <%= f.buttons do %>
        <%= f.commit_button :label => "Login", :button_html => { :class => "button primary submit"} %>
      <% end %>
 
      <br/>
    <% end %>
 
    <%= render :partial => 'layouts/devise/devise_error_messages' %>
 
  </section>
 
</div>

app/views/static/loggedout.html.erb

<section id="content">
 
  <h1>Logged Out</h1>
 
  <hr/>
 
  <p>This is not an error page but an indication that you have lost your session.</p>
 
  <p><b>So why are you here?</b></p>
 
  <ul>
    <li>- You have successfully logged out after clicking the "Logout" button.</li>
    <li>- You logged in to another machine so we logged this session out. We don't want to have multiple logins everywhere for security purposes.</li>
    <li>- You have been inactive for a while, we logged this session out.</li>
  </ul>
 
  <p><b><%= link_to "Login", new_user_session_path, :class => "button" %></b></p>
</section>

config/routes.rb

  devise_for :users, :controllers => { :sessions => "sessions" }
 
  ..
  match "loggedout" => "static#loggedout"
 end

db/migrate/20120223022102_add_login_token_to_users.rb

class AddLoginTokenToUsers < ActiveRecord::Migration
  def self.up
    PgTools.restore_default_search_path
 
    change_table "users" do |t|
      t.string "login_token"
    end
  end
 
  def self.down
    PgTools.restore_default_search_path
 
    change_table "users" do |t|
      t.remove "login_token"
    end
  end
end