You can track a specific user session by storing a unique token specific to that user in the database.
Create a migration to add a token storage field. I assume that the development model is a User.
class AddSignInTokenToUsers < ActiveRecord::Migration def change add_column :users, :current_sign_in_token, :string end end
Add the following code to application_controller.rb
class ApplicationController < ActionController::Base before_filter :invalidate_simultaneous_user_session, :unless => Proc.new {|c| c.controller_name == 'sessions' and c.action_name == 'create' } def invalidate_simultaneous_user_session sign_out_and_redirect(current_user) if current_user && session[:sign_in_token] != current_user.current_sign_in_token end def sign_in(resource_or_scope, *args) super token = Devise.friendly_token current_user.update_attribute :current_sign_in_token, token session[:sign_in_token] = token end end
sign_in(resource_or_scope, *args) is a developer hook that will be called every time a user logs in.
invalidate_simultaneous_user_session will exit the current user if another instance of the current user logs on to it. This ensures that only one session will be active for the user at any given time.
invalidate_simultaneous_user_session filter should be skipped for user action in order to update the newly registered user token. I am not happy with using Proc to skip a filter based on the name and action of the controller. If you have already redefined the sessions_controller program, enable skip_before_filter :check_simultaneous_user_session inside this controller, and you can get rid of Proc!
Hope this helps.
source share