目前,我可以判断一个用户是否已经登录以及它已经在线多长时间,但我无法确定用户是否已从其他浏览器退出。这是我目前的代码:
- 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)"
答案 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