在我的应用程序中,我将Devise设置为在30分钟后超时。哪个工作正常...用户必须在此之后再次登录。我唯一的问题是,在会话超时后,设计显然不会在会话控制器中使用销毁操作。因此,用户的属性:signed_in未设置为“false”。 因此,即使会话超时后,该用户仍显示为在线。 有没有办法在超时后销毁会话,或者在一段时间后将浏览器关闭后将signed_in属性设置为false?
我在会话控制器中的销毁操作:
def destroy
current_user.try("signed_in=", false); current_user.save
signed_in = signed_in?(resource_name)
sign_out_and_redirect(resource_name)
set_flash_message :notice, :signed_out if signed_in
end
答案 0 :(得分:4)
我不是Devise的专家,但我怀疑这是因为HTTP的无状态特性。设备只知道当用户在超时长度后再次尝试访问页面时会话超时,并且当用户实际注销并且在会话控制器上调用destroy方法时,可能只调用destroy方法。
为了实现您可能正在寻找的东西,您需要运行一个后台进程来扫描旧会话,然后手动调用destroy方法(或执行类似的操作)。
答案 1 :(得分:1)
使用新的Devise版本,其工作方式如下,以获得准确的在线/离线状态:
将它放在你的application_controller中:
before_filter :last_request
def last_request
if user_signed_in?
if current_user.last_request_at < 1.minutes.ago
current_user.update_attribute(:last_request_at, Time.now)
end
if current_user.currently_signed_in = false
current_user.update_attribute(:currently_signed_in, true)
end
end
end
对于每个操作,应用都会检查上一个请求是否超过1分钟,如果是,则更新用户属性。
将它放在user.rb中:
before_save :set_last_request
Warden::Manager.after_authentication do |user,auth,opts|
user.update_attribute(:currently_signed_in, true)
end
Warden::Manager.before_logout do |user,auth,opts|
user.update_attribute(:currently_signed_in, false)
end
def set_last_request
self.last_request_at = Time.now
end
def signed_in?
if self.currently_signed_in
if self.timedout?(self.last_request_at.localtime)
return false
else
return true
end
else
false
end
end
然后你可以使用signed_in?确定用户在线状态的方法。