设计 - 如果同一用户从其他浏览器/计算机登录,则会使用户会话无效

时间:2011-09-09 09:39:48

标签: ruby-on-rails-3 devise

我有一个场景,我需要限制用户一次只有一个活动会话。我是一个rails3应用程序,并使用设计进行身份验证。我有兴趣只保留最新的用户会话。即,如果用户登录时有另一个会话对同一用户名有效,我想停用较旧的会话并允许最近的会话。有没有办法在设计中掌握用户会话并使其无效?

2 个答案:

答案 0 :(得分:15)

您可以通过在数据库中存储特定于该用户的唯一标记来跟踪特定用户的会话。

创建迁移以添加用于存储令牌的字段。我假设设计模型是用户。

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来根据控制器名称和操作跳过过滤器。如果您已经覆盖了设计sessions_controller,那么在该控制器中包含skip_before_filter :check_simultaneous_user_session,您就可以摆脱Proc!

希望这会有所帮助..

答案 1 :(得分:2)

有关rails 4的更新设计, 您可以根据此

更改代码

http://pastebin.com/p6mvC8T3