Devise - 如果同一用户从不同的浏览器/机器登录,则无效用户会话 [英] Devise - Invalidate user session if the same user logs in from a different browser/machine

查看:112
本文介绍了Devise - 如果同一用户从不同的浏览器/机器登录,则无效用户会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

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



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

  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'和c.action_name =='create'}

def invalidate_simultaneous_user_session
sign_out_and_redirect(current_user)if current_user&&会话[: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,令牌
会话[:sign_in_token] =令牌
结束
结束

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 !



希望这有帮助..


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?

解决方案

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..

这篇关于Devise - 如果同一用户从不同的浏览器/机器登录,则无效用户会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆