I'm trying to implement the :lockable module to my devise following this wiki but ran into some issues. In development, when login attempted more than maximum_attempts times, the failed_attempts attribute gets updated correctly and the user account gets locked but:
1) despite config.last_attempt_warning = true no warning message is displayed
2) I get an unlock_instructions email, but when I copy paste the link into the browser, I get an invalid authorisation token error.
config/initializers/devise.rb
# ==> Configuration for :lockable
config.lock_strategy = :failed_attempts
config.unlock_keys = [:email]
config.unlock_strategy = :email
config.maximum_attempts = 3
config.last_attempt_warning = true
models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :confirmable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :lockable
end
views/devise/sessions/new
= flash[:alert] if flash[:alert]
= flash[:notice] if flash[:notice]
= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
  .form-inputs
    = f.input :email, required: false, autofocus: true
    = f.input :password, required: false, autocomplete: "off"
    = f.input :remember_me, as: :boolean if devise_mapping.rememberable?
  .form-actions
    = f.button :submit, "Log in"
db/migrate/YYYYMMDDxxx_add_lockable_to_devise.rb
class AddLockableToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :failed_attempts, :integer, default: 0, null: false
    add_column :users, :unlock_token, :string
    add_column :users, :locked_at, :datetime
    add_index :users, :unlock_token, unique: true
  end
end
I don't have any migrations pending, also tried resetting the db and restarting the server but with no luck. Any ideas on what I'm doing wrong? Thanks in advance.
After lots of digging, I managed to solve both issues:
The first issue was caused by the config:
config/initializers/devise.rb
config.paranoid = true
If you have a look at the devise module:
If set to paranoid mode, do not show the locked message because it leaks the existence of an account.
Depending on your security requirements, you can either change this value to false or keep the emails secret and not provide feedback.
If you're interested in customising your message on failed log in attempts I strongly recommend reading this.
The second issue was caused by me copying the link directly from the source code of the email - since = is encoded as 3D=, the link was obviously breaking. Further explanation here. 
Hope this helps someone if they run into similar issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With