[英]Rails 3 + Devise: log out user after timeout
In my app I set Devise to timeout a session after 30 minutes. 在我的应用程序中,我将Devise设置为在30分钟后超时。 Which works fine... the user has to log in again after that time. 哪个工作正常...用户必须在此之后再次登录。 My only problem is that devise apparently doesn't use the destroy action in the session controller after a session has timed out. 我唯一的问题是,在会话超时后,设计显然不会在会话控制器中使用销毁操作。 So the attribute :signed_in for the user isn't set to 'false'. 因此,用户的属性:signed_in未设置为“false”。 So even after a session has timed out this user is still displayed as online. 因此,即使会话超时后,该用户仍显示为在线。 Is there a way to destroy the session after the timeout or set the signed_in attribute to false after a certain time and on browser close? 有没有办法在超时后销毁会话或在一段时间后在浏览器关闭后将signed_in属性设置为false?
My destroy action in session controller: 我在会话控制器中的销毁操作:
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
I'm not exactly an expert on Devise but I suspect this is because of the stateless nature of HTTP. 我不是Devise的专家,但我怀疑这是因为HTTP的无状态特性。 Devise only knows a session is timed out when the user tries to access a page again after your timeout length and will likely only call the destroy method when a user actually logs out and the destroy method is called on the session controller. 当用户在超时长度后尝试再次访问页面时,Devise只知道会话超时,并且当用户实际注销并且在会话控制器上调用destroy方法时,可能只调用destroy方法。
In order to achieve what you are likely looking for, you would need to run a background process that sweeps for old sessions and then manually calls the destroy method (or does something similar). 为了实现您可能正在寻找的东西,您需要运行一个后台进程来扫描旧会话,然后手动调用destroy方法(或执行类似的操作)。
With the new Devise version it works as follows to have an accurate online/offline status: 使用新的Devise版本,其工作方式如下,以获得准确的在线/离线状态:
put this in your application_controller: 把它放在你的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
With every action the app checks if the last request was over 1min ago, if yes, he updates the user attribute. 对于每个操作,应用程序检查最后一个请求是否超过1分钟,如果是,则更新用户属性。
put this in user.rb: 把它放在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
you can then use the signed_in? 然后你可以使用signed_in? method to determine a users online status. 确定用户在线状态的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.