在使用设计的Rails中:如何确定用户是否已从其他浏览器注销?

时间:2015-11-30 05:06:09

标签: ruby-on-rails devise

目前,我可以判断一个用户是否已经登录以及它已经在线多长时间,但我无法确定用户是否已从其他浏览器退出。这是我目前的代码:

- if current_user
 = "(last login #{time_ago_in_words(user.current_sign_in_at)} ago) - #{user.current_sign_in_at ? 'currently online' : ''}"
- else
 = "(last login #{time_ago_in_words(user.current_sign_in_at)} ago)"

2 个答案:

答案 0 :(得分:0)

据我所知,在Devise中没有具体的内容。您可以通过在数据库中存储特定于该用户的唯一标记来跟踪特定用户的会话。

创建迁移以添加用于存储令牌的字段。

每次注销都要检查令牌,您可以保存时间戳。

我想是这样的,你知道用户何时从哪个浏览器注销。

希望它有所帮助!

答案 1 :(得分:0)

你可以尝试

在会话中存储时间戳,以便在一段时间不活动后暂停会话。如果您使用Devise,则可以使用timeoutable module轻松实现此目的。这提出了一个小难题:如果你将超时设置得太低,那么对你的用户来说这会非常烦人。但是超时时间越长,安全性就越小(如果攻击者在达到超时之前进入,他们可以保持刷新以保持会话活动)。

跟踪服务器端的活动会话ID(同时仍将实际会话数据存储在cookie中)。这意味着您可以随时使会话无效。

添加SessionActivation模型以跟踪哪些会话处于活动状态。这是迁移:

class AddUserActiveSessions < ActiveRecord::Migration
  def change
    create_table :session_activations do |t|
      t.integer :user_id,   null: false
      t.string :session_id, null: false
      t.timestamps
    end

    add_index :session_activations, :user_id
    add_index :session_activations, :session_id, unique: true
  end
end

这是班级:

class SessionActivation < ActiveRecord::Base
  LIMIT = 20

  def self.active?(id)
    id && where(session_id: id).exists?
  end

  def self.activate(id)
    activation = create!(session_id: id)
    purge_old
    activation
  end

  def self.deactivate(id)
    return unless id
    where(session_id: id).delete_all
  end

  # For some reason using #delete_all causes the order/offset to be ignored
  def self.purge_old
    order("created_at desc").offset(LIMIT).destroy_all
  end

  def self.exclusive(id)
    where("session_id != ?", id).delete_all
  end
end

对用户模型进行一些更改:

class User < ActiveRecord::Base
  # ...

  has_many :session_activations, dependent: :destroy

  def activate_session
    session_activations.activate(SecureRandom.hex).session_id
  end

  def exclusive_session(id)
    session_activations.exclusive(id)
  end

  def session_active?(id)
    session_activations.active? id
  end


end