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

我有一个场景,我需要限制用户一次只有一个活动会话.我是一个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!

希望这可以帮助..

相关文章

以下代码导致我的问题: class Foo def initialize(n=0) @n = n end attr_accessor :n d...
这是我的spec文件,当为上下文添加测试“而不是可单独更新用户余额”时,我得到以下错误. require 's...
我有一个拦截器:DevelopmentMailInterceptor和一个启动拦截器的inititializer setup_mail.rb. 但我想将...
例如,如果我有YAML文件 en: questions: new: 'New Question' other: recent: ...
我听说在RSpec中避免它,let,let !,指定,之前和主题是最佳做法. 关于让,让!之前,如果不使用这些,我该如...
我在Rails中使用MongoDB和mongo_mapper gem,项目足够大.有什么办法可以将数据从Mongoid迁移到 Postgres...