1

I would like to detect failed login attempts and I want to avoid monkey-patching.

Initially, I thought that I can simply use the Warden before_failure hook:

Warden::Manager.before_failure do |env, opts|
  # failed login?
end

However, this doesn't work as expected - the hook is also being called when you try to access an authenticated resource while not being authenticated - not just a failed login attempt specifically.

I've found that Devise::SessionsController passes a recall key to Warden during authentication. It means that the code below would technically work:

Warden::Manager.before_failure do |env, opts|
  next unless opts.key?(:recall)

  # failed login attempt!
end

However, this doesn't seem like an "official" solution and I can't find any suggestions on how to handle this in the Devise docs. How should I solve this without monkey-patching the SessionsController?

Kacper Madej
  • 79
  • 2
  • 5
  • 1
    Does this answer your question? [Devise: Registering log in attempts](https://stackoverflow.com/questions/8170324/devise-registering-log-in-attempts) – Greg Jul 11 '23 at 10:53

1 Answers1

1

You can use the before_failure method, just need check if there were any parameters passed. If there weren't -- it's not a failed attempt. Change :user to whatever your model is.

 Warden::Manager.before_failure do |env, opts|
    email = env["action_dispatch.request.request_parameters"][:user] &&
            env["action_dispatch.request.request_parameters"][:user][:email]

    unless email.blank?
      ## login failed - do something
    end
   
  end
dbugger
  • 15,868
  • 9
  • 31
  • 33