如何判断给定的Devise用户是否已立即登录?

Nat*_*ong 4 devise ruby-on-rails-3.1

在使用Devise的Rails应用程序中,有没有办法判断特定用户现在是否已登录?

我知道视图助手,user_signed_in?.我正在寻找的更像是:

User.all.each do |user|
  puts user.signed_in?
end
Run Code Online (Sandbox Code Playgroud)

我看到Devise已经添加了一current_sign_in_atusers.但是,NULL当用户退出时,这不会被设置,因此我无法对此进行测试.

如何检查用户当前是否已登录?

yuя*_*uяi 6

您可以将一个before_filter添加到ApplicationController,以在users表的last_request_at字段中设置当前日期/时间,您必须先通过迁移添加该字段.在before_filter调用的方法中,您当然要确保首先验证用户身份.并且您可能希望除了过滤器之外不需要身份验证的操作.

然后,假设您已在用户模型中包含Timeoutable模块,您可以通过这样的调用来查看用户的会话是否是最新的:

user.timedout?(user.last_request_at)
Run Code Online (Sandbox Code Playgroud)

在Timeoutable模块中定义的timedout?(last_access)方法将比较Devise会话超时与上一个请求时间/日期.

作为旁注,如果最后一个last_request_at值大于一分钟(或您选择的任何时间间隔),您可能只想更新last_request_at.否则,如果您的页面通过AJAX进行了大量的控制器调用,那么在一个请求中会有很多不必要的数据库更新.


Zac*_*ker 4

您是否正在尝试跟踪用户是否已登录并且会话处于活动状态,或者用户现在是否在网站上?

为了跟踪用户是否登录,您需要向 Warden 添加回调,并在每次加载页面时更新时间戳,然后如果他们在超过 X 时间段内没有执行任何操作,您就认为他们已注销。您可以通过以下方式执行此操作:

Warden::Manager.after_authentication do |user, auth, opts|
    if user.last_action <= 5.minutes.ago.utc
        user.last_action = Time.now
        user.save
    end
end
Run Code Online (Sandbox Code Playgroud)

如果您想查看是否有活跃季节并且尚未明确注销,则可以是以下内容:

Warden::Manager.before_logout do |user, auth, opts|
    user.current_sign_in_at = nil
    user.save
end
Run Code Online (Sandbox Code Playgroud)