Custom message on devise lockable n-th attempt

2019-07-25 09:39发布

问题:

I'm looking for a method to display custom messages for a various numbers of failed attempts in devise lockable module.

I found out that only the last attempt could be notified by default: https://github.com/plataformatec/devise/blob/master/lib/devise/models/lockable.rb#L121

Is there any elegant way to display different warning message for say 7th, and 8th failed attempt? Could you propose one?

回答1:

maybe a custom SessionsController, I'm guessing that devise uses dynamic methods, I couldn't find where :last_attempt was called to just override the unauthenticated_message method

def create
    if self.resource.failed_attempts != self.resource.class.maximum_attempts - 1 and self.resource.failed_attempts != 0
        attempts_left = self.resource.failed_attempts
        flash[:alert] = I18n.t 'some_path.errors.attempts', attempts_left: attempts_left
    super
end

The idea is to add a flash alert when you have 1 or less than the max attempts, in the max attempt case and the last attempt case you would get the default messages



回答2:

The idea is interesting but won't work because lockable is called before create, so I created a custom action which I call before create.

This worked for me:

class User::SessionsController < Devise::SessionsController
  before_action :check_failed_attempts, only: :create

  def after_sign_in_path_for(user)
    # some code
  end

  def create
    super
    # create some stuff and check others
  end

  def destroy
    # may be destroy and deal with cookies
    super
  end

  def check_failed_attempts
    flash.clear

    email = self.params["user"]["email"]
    return unless email

    user = User.find_by_email(email)
    return unless user

    failed_attempts = user.failed_attempts
    maximum_attempts = User.maximum_attempts
    attempts_left = maximum_attempts - failed_attempts - 1
    if attempts_left != maximum_attempts and attempts_left > 1
      flash[:notice] = I18n.t 'devise.failure.n_attempt', attempts_left: attempts_left
    end
  end
end