Devise:rememberable意味着last_sign_in_at没有被trackable更新

发布于 2024-12-25 14:14:29 字数 222 浏览 1 评论 0原文

我一直在使用 Devise,并依靠用户模型的 last_sign_in_at 来确定我的客户是否在 X 天内没有返回。然而,我最近发现,last_sign_in_at 仅在实际表单登录事件发生时更新,而不是在用户由于包含可记住而自动登录时更新。

如果想确保每次用户登录(新的浏览器会话)时都会更新last_sign_in_at,无论他们是使用表单登录还是通过可记住的cookie自动登录,我将如何在设计兼容的方式?

I have being using Devise, and relying on last_sign_in_at of the user model to work out if my customers have not returned within X days. However, I recently discovered that last_sign_in_at is only updated when an actual form log in event occurs, as opposed to when a user is logged in automatically due to the inclusion of rememberable.

If want to ensure that last_sign_in_at is updated each time a user logs in (a new browser session), regardless of whether they used a form to log in or were automatically logged in by the rememberable cookie, how would I go about doing this in a Devise-compatible way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

衣神在巴黎 2025-01-01 14:14:29

采用 Matthew 的解决方案,我认为代码应该如下(注意 session[:logged_signin] 之前的非运算符):

before_filter :update_last_sign_in_at

protected

def update_last_sign_in_at
  if user_signed_in? && !session[:logged_signin]
    sign_in(current_user, :force => true)
    session[:logged_signin] = true
  end
end

Taking Matthew's solution, I think the code should be the following (note the not-operator before the session[:logged_signin]):

before_filter :update_last_sign_in_at

protected

def update_last_sign_in_at
  if user_signed_in? && !session[:logged_signin]
    sign_in(current_user, :force => true)
    session[:logged_signin] = true
  end
end
瑾兮 2025-01-01 14:14:29

可跟踪挂钩来自 Warden 的 after_set_user 挂钩 - - 为了轻松解决这个问题,您可以设置一个 before_filter 来调用 登录

这可以优化,但测试一下使用是否

before_filter proc{ sign_in(current_user, :force => true) }

更新了last_signed_in_at时间戳。

The trackable hook is from Warden's after_set_user hook -- what you could do to easily remedy this is set a before_filter to call sign_in.

This could be optimized, but test to see if using

before_filter proc{ sign_in(current_user, :force => true) }

updates the last_signed_in_at timestamp.

沫离伤花 2025-01-01 14:14:29

设计:可记住意味着last_sign_in_at未通过 trackable 更新

扩展以前的解决方案,它们的问题是,如果用户正常登录,他们将“登录两次”。这会将 last_sign_in_at 设置为与 current_sign_in_at 相同(或几乎相同)的值。
在我的网站上,我使用 last_sign_in_at 让用户知道自上次访问该网站以来发生了什么,因此我需要它稍微准确。此外,它还会记录 +1 登录计数。

此外,有些人(像我一样)将浏览器窗口打开几天而不关闭它(因此从不清除会话标志)。出于度量目的等,如果此类用户行为有时会刷新 current_sign_in_at 时间,这可能会很有用。

下面的变体将解决这些问题。

class ApplicationController < ActionController::Base
  before_filter :update_sign_in_at_periodically
  UPDATE_LOGIN_PERIOD = 10.hours

  protected

  def update_sign_in_at_periodically
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago
      session[:last_login_update_at] = Time.now
      sign_in(current_user, :force => true) if user_signed_in?
    end
  end
end

但是,当我使用 Devise 3.2.4 尝试上述操作时,当它通过 cookie 自动登录时(登录计数 +1 和 current_sign_in_at 设置),我确实获得了新的登录信息。因此,我只剩下一个问题,即希望跟踪定期更新,即使对于保持会话打开的用户也是如此。

class ApplicationController < ActionController::Base
  before_filter :update_sign_in_at_periodically
  UPDATE_LOGIN_PERIOD = 10.hours 

  protected 

  def update_sign_in_at_periodically
    # use session cookie to avoid hammering the database
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago
      session[:last_login_update_at] = Time.now
      if user_signed_in? and current_user.current_sign_in_at < 1.minute.ago # prevents double logins
        sign_in(current_user, :force => true)
      end
    end
  end
end

Devise: rememberable means that last_sign_in_at is not updated by trackable

Expanding on previous solutions, the problem with them would be that if the user signs in normally, they will "sign in twice". Which will set last_sign_in_at to the same (or almost the same) value as current_sign_in_at.
On my site, I use last_sign_in_at to let the user know what has happened since last time they visited the site, and as such I need it to be somewhat accurate. Also, it logs +1 login count.

Also, there are people (like myself) who leave a browser window open for days without closing it (and hence never clearing the session flag). For metric purposes etc, it can be useful if such user behavior sometimes refresh the current_sign_in_at time.

The below variants will remedy these things.

class ApplicationController < ActionController::Base
  before_filter :update_sign_in_at_periodically
  UPDATE_LOGIN_PERIOD = 10.hours

  protected

  def update_sign_in_at_periodically
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago
      session[:last_login_update_at] = Time.now
      sign_in(current_user, :force => true) if user_signed_in?
    end
  end
end

However, when I try the above, using Devise 3.2.4, I do get a new login when it auto-logins by cookie (login-count +1 and current_sign_in_at being set). So, I'm left with only the issue of wanting the tracking to periodically update even for users which keep the session open.

class ApplicationController < ActionController::Base
  before_filter :update_sign_in_at_periodically
  UPDATE_LOGIN_PERIOD = 10.hours 

  protected 

  def update_sign_in_at_periodically
    # use session cookie to avoid hammering the database
    if !session[:last_login_update_at] or session[:last_login_update_at] < UPDATE_LOGIN_PERIOD.ago
      session[:last_login_update_at] = Time.now
      if user_signed_in? and current_user.current_sign_in_at < 1.minute.ago # prevents double logins
        sign_in(current_user, :force => true)
      end
    end
  end
end
想念有你 2025-01-01 14:14:29

application_controller 上,您可以设置一个 before_action 来检查当前用户的 current_sign_in_at 是否比 X 前更长。如果是,则使用 sign_in(current_user, force: true) 更新 current_sign_in_at。

before_action :update_last_sign_in_at

def update_last_sign_in_at
   return unless user_signed_in? && current_user.current_sign_in_at < 12.hours.ago
   sign_in(current_user, force: true)
end

我用它来检测不活动的用户(6 个月未登录)并删除它们。 #GDPR

On the application_controller you can set a before_action that checks if the current_sign_in_at of the current user is longer then X ago. If it is, then use sign_in(current_user, force: true) that updates the current_sign_in_at.

before_action :update_last_sign_in_at

def update_last_sign_in_at
   return unless user_signed_in? && current_user.current_sign_in_at < 12.hours.ago
   sign_in(current_user, force: true)
end

I use it so to detect inactive users (not signed in for 6 months) and delete them. #GDPR

玩物 2025-01-01 14:14:29

AFAIK 您还可以在该 current_user 模型上使用 update_tracked_fields!

AFAIK you can also use update_tracked_fields! on that current_user model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文