Devise: запоминаемый означает, что last_sign_in_at не обновляется отслеживаемым

Я использую Devise и полагаюсь на last_sign_in_at пользовательской модели, чтобы выяснить, не вернулись ли мои клиенты в течение X дней. Однако недавно я обнаружил, что last_sign_in_at обновляется только тогда, когда происходит фактическое событие входа в форму, а не когда пользователь автоматически входит в систему из-за включения запоминаемого элемента.

Если вы хотите, чтобы last_sign_in_at обновлялся каждый раз, когда пользователь входит в систему (новый сеанс браузера), независимо от того, использовали ли они форму для входа в систему или были автоматически зарегистрированы с помощью запоминаемого файла cookie, как мне поступить в Разработать совместимый способ?

5 ответов

Решение

Отслеживаемый хук происходит от хука Warden after_set_user - что вы можете сделать, чтобы легко исправить это, - установить before_filter для вызова sign_in.

Это может быть оптимизировано, но проверьте, чтобы использовать

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

обновляет отметку времени last_signed_in_at.

Принимая решение Мэтью, я думаю, что код должен быть следующим (обратите внимание на оператор not перед сеансом [: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

На 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

Devise: запоминаемый означает, что last_sign_in_at не обновляется отслеживаемым

Развивая предыдущие решения, проблема с ними будет заключаться в том, что если пользователь войдет в систему в обычном режиме, он "войдет в систему дважды". Который установит 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

AFAIK вы также можете использовать update_tracked_fields! на что current_user модель.

Другие вопросы по тегам