I have a scenario where i need to restrict users from having only one active session at a time. Mine is a rails3 application and uses devise for authentication. I'm interested in keeping only the latest user session active. i.e., if a user logs in while there is another session active for the same username, i want to inactivate the older session and allow the recent one. Is there a way, in devise, to get hold of user sessions and invalidate them?
问题:
回答1:
You can track a particular user's session by storing a unique token specific to that user in the database.
Create a migration to add the field for storing the token. I assume the devise model is 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 devise hook that will be called every time the user logs in.
invalidate_simultaneous_user_session
will log out the current user if another instance of the current user logs in. This will ensure that only one session is active for a user at any instance of time.
invalidate_simultaneous_user_session
filter should be skipped for the user login action to update the newly logged in user's token. I am not happy with using a Proc to skip the filter based on controller name and action. If you have already overridden devise's sessions_controller
, then include skip_before_filter :check_simultaneous_user_session
inside that controller and you can get rid of the Proc!
Hope this helps..
回答2:
For updated devise for rails 4, you may change the code according to this
http://pastebin.com/p6mvC8T3