我有一个场景,我需要限制用户一次只有一个活动会话.我是一个rails3应用程序,并使用设计进行身份验证.我有兴趣只保留最新的用户会话.即,如果用户登录时有另一个会话对同一用户名有效,我想停用较旧的会话并允许最近的会话.在设计中,是否有办法获取用户会话并使其无效?
解决方法
您可以通过在数据库中存储特定于该用户的唯一标记来跟踪特定用户的会话.
class AddSignInTokenToUsers < ActiveRecord::Migration def change add_column :users,:current_sign_in_token,:string end end
将以下代码添加到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)是一个设计钩子,每次用户登录时都会调用它.
如果当前用户的另一个实例登录,invalidate_simultaneous_user_session将注销当前用户.这将确保在任何时刻只有一个会话对用户是活动的.
应跳过invalidate_simultaneous_user_session过滤器,以便用户登录操作更新新登录用户的令牌.我不满意使用Proc来根据控制器名称和操作跳过过滤器.如果你已经覆盖了devise的sessions_controller,那么在该控制器中包含skip_before_filter:check_simultaneous_user_session,你可以摆脱Proc!
希望这可以帮助..