web-dev-qa-db-ja.com

エラーが「empty_username」または「empty_password」の場合は、「wp_login_failed」アクションフックを使用してユーザーをリダイレクトします。

バックグラウンド

私はまだwp-login.phpをそこにたどり着く方法を知っているユーザーに利用可能なままにしている間、私はブログのために見えないフロントエンドログインをすることを試みています。 wp-login.phpはフロントエンドログインを認証するためにも必要であるため、完全に削除することはできません。

もうすぐそこにありますが、ログイン失敗、特に空のユーザー名に関する問題が1つあります。

質問

ユーザーがwp-login.phpに直接アクセスしたときに同じ理由でエラーが表示されないようにしながら、空のユーザー名/パスワードエラーに対してwp-login.phpが表示されないようにする方法を知っている人はいますか?

私の仕事

wp_login_failedフックを見つけて、以下の関数を作成しました。基本的には、ログインが失敗したこと、およびユーザーをフロントエンドログインにリダイレクトする前に入力されたユーザー名を確認するためのクエリ引数を追加します。クエリ引数を使用して、ログインが失敗した理由を特定し、ユーザーにメッセージを表示できます。

add_action('wp_login_failed', 'djg_front_end_login_fail');
function djg_front_end_login_fail($username){

    $referrer = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : $_SERVER['PHP_SELF'];
    $referrer = add_query_arg('result', 'failed', $referrer);
    $referrer = add_query_arg('username', $username, $referrer);

    if(!empty($referrer) && !strstr($referrer, 'wp-login') && !strstr($referrer, 'wp-admin')) :
        wp_redirect($referrer);
        exit;
    endif;

}

しかし、usernameフィールドが空の場合はリダイレクトされず、代わりにwp-login.phpが表示されていることに気付きました。

さらに調べてみると、最初のログインエラーがempty_usernameまたはempty_passwordのいずれかである場合にwp_login_failedアクションフックが追加されていないことに気付いたwp_authenticate()関数が見つかりました。これに対処するために、私はauthenticateフィルタフックを使用し、実際には前述のエラーのコードを変更し、それらのコードにdjg_を追加して、それらが無視されないようにしました。

add_filter('authenticate', 'djg_authenticate_login', 99, 3);
function djg_authenticate_login($user, $username, $password){;

    if(is_wp_error($user)) :

        $codes = $user->get_error_codes();
        $messages = $user->get_error_messages();

        $user = new WP_Error;

        for($i = 0; $i <= count($codes) - 1; $i++) :

            $code = $codes[$i];
            if(in_array($code, array('empty_username', 'empty_password'))) :
                $code = 'djg_' . $code;
            endif;

            $user->add($code, $messages[$i]);

        endfor;

    endif;

    return $user;

}

これはうまくいきますが、ユーザがwp-login.phpページに直接アクセスすると( Background で説明されているように)利用可能なままでなければならない場合、エラーが表示されます -

エラー:ユーザー名フィールドが空です。
エラー:パスワード欄が空です。

最後に、たくさんの髪の毛を引っ張った後、私はwp_signon()関数でこれを引き起こしているコードを見つけました、しかし私の目には私がスニペットのまわりでどこでも振る舞いを変えることを可能にするフィルタを見ることができません。基本的には、エラーが正確にempty_usernameempty_passwordである場合は無視してください。 -

if ( is_wp_error($user) ) {
    if ( $user->get_error_codes() == array('empty_username', 'empty_password') ) {
        $user = new WP_Error('', '');
    }

    return $user;
}

詳細

  • wp_authenticate()/wp-includes/pluggable.phpにあります
  • authenticateフィルタフックはwp_authenticate()関数内にあります。
  • wp_login_failedアクションフックはwp_authenticate()関数内にあります。
  • wp_signon()/wp-includes/user.phpにあります

質問(また)

ユーザーが空のユーザー名のエラーに対してwp-login.phpの表示を停止すると同時に、同じ理由でユーザーがwp-login.phpにアクセスしたときにエラーが表示されないようにする方法を知っている人はいますか。

6
David Gard

WordPressは2つの方法で失敗したログインを処理します。

  1. それが不適切な認証情報で、ユーザー名とパスワードの両方に値がある場合、このアクションはwp_login_failedによって取得できます。
  2. 両方または片方のオプションが空の場合、WordPressは認証オブジェクトフィルタの最初のパラメータとしてエラーオブジェクトを生成します。開かず、wp_login_failedアクションがこの原因/イベントを捉えます

ここで行ったことについては、コード内のコメントを参照してください。

add_filter( 'authenticate', function( $user, $username, $password ) {
    // forcefully capture login failed to forcefully open wp_login_failed action, 
    // so that this event can be captured
    if ( empty( $username ) || empty( $password ) ) {
        do_action( 'wp_login_failed', $user );
    }
    return $user;
}, 10, 3 );

// to handle even you can handle the error like
add_action( 'wp_login_failed', function( $username ) {
    if ( is_wp_error( $username ) ) {
        // perform operation on error object for empty error
    }
} );
7
palash140