認証失敗後のデバイスログ



Devise Log After Auth Failure



解決:

前のSOの質問に対するこの回答-考案:ログイン試行の登録に回答があります。

deviseコントローラーの作成アクションはwarden.authenticate!を呼び出します。これは、指定されたパラメーターを使用してユーザーを認証しようとします。認証が失敗した場合は、認証してください。 devise失敗アプリを呼び出し、次にSessionsController#newアクションを実行します。認証が失敗した場合、作成アクション用のフィルターは実行されないことに注意してください。



したがって、解決策は、env ['warden.options']の内容をチェックし、適切なアクションを実行する新しいアクションの後にフィルターを追加することです。

私は提案を試し、成功したログイン試行と失敗したログイン試行の両方をログに記録することができました。関連するコントローラーコードは次のとおりです。



class SessionsController:new def create super :: Rails.logger.info ' n ***  n email_idでのログインに成功しました:#{request.filtered_pa​​rameters [' user ']}  n ***  n'end private def log_failed_login: :Rails.logger.info ' n ***  n email_idでのログインに失敗しました:#{request.filtered_pa​​rameters [' user ']}  n ***  n'if failed_login? def failed_loginを終了しますか? (options = env ['warden.options'])&& options [:action] == 'unauthenticated' end end

ログには次のエントリがあります。

ログインを成功させるには

POSTを開始しました '/ users / sign_in' ... ... *** email_idで正常にログインしました:{'email' => ... *** ......完了しました302が見つかりました

ログインに失敗した場合

POST '/ users / sign_in'を開始しました......完了しました401SessionsControllerによる不正な処理を完了しました#newas HTML ... ... *** email_idでのログインに失敗しました:{'email' => ... *** ......完了302が見つかりました 

プラカシュの答えは役に立ちますが、頼るのは理想的ではありませんSessionsController#newは、副作用として実行されます。私はこれがよりきれいだと信じています:

クラスLogAuthenticationFailure 

Wardenのコールバックにフックしたい場合は、Graemeの回答を確認してください(DeviseはWardenを使用して実装されています)。




同じ質問がありましたが、を使用して解決できませんでした'warden.options'私の場合、これらはにリダイレクトする前にクリアされていたのでsessions#newアクション。脆弱すぎると判断したいくつかの代替案を調べた後(いくつかのDeviseクラスの拡張と既存のメソッドのエイリアス化が含まれていたため)、によって提供されるいくつかのコールバックを使用することになりました。ワーデン。コールバックは現在の要求/応答サイクル内で呼び出され、パラメーターはすべてenvオブジェクト。

これらのコールバックには名前が付けられており、この問題および関連する問題を解決するように設計されているようです。そして、それらは文書化されています!

Wardenは、現在、次のコールバックをサポートしていますワーデン-1.2.3:

  • after_set_user
  • after_authentication (正常なサインインのログ記録に役立ちます)
  • after_fetch(のエイリアスafter_set_user)
  • before_failure (失敗したサインインのログ記録に役立ちます-以下の例)
  • after_failed_fetch
  • before_logout
  • 要求に応じて

各コールバックはに直接設定されますWarden :: Managerクラス。失敗した認証の試行を追跡するために、これを追加しました。

Warden :: Manager.before_failure do | env、opts | email = env ['action_dispatch.request.request_parameters'] [:user] && env ['action_dispatch.request.request_parameters'] [:user] [:email]#残念ながら、Userオブジェクトは#取得するまでに失われています。ここ; #メールがシステムのユーザーアカウントと一致するかどうかを確認したいので、dbヒットを取得しますuser_exists = User.where(email:email).exists? if opts [:message] ==:unconfirmed#:confirmableを使用しているため、これは私にとって特別なケースです。#ログインは正しいのですが、ユーザーは#メールアドレスをまだ確認していません:: Rails.logger.info '***ログイン失敗:未確認のアカウントアクセス:#{email}' elsif opts [:action] == 'unauthenticated'# 'unauthenticated'は、!user_exists#bad email:#このメールアドレスでユーザーが見つからない場合にログイン失敗を示します:: Rails.logger.info '***ログインの失敗:間違ったメールアドレスが指定されました:#{email}' else#ユーザーはデータベースに存在します。不正なパスワードである必要があります:: Rails.logger.info '***ログインの失敗:電子メールとパスワードの不一致:#{email} 'end end end

私はあなたが使用できることを期待していますログアウトアクションを追跡するためのbefore_logoutコールバックもありますが、私はそれをテストしていません。あるようですコールバックのprepend_バリアントも同様です。