web-dev-qa-db-ja.com

登録後にユーザーが自分の電子メールを確認したことをどのように確認できますか?

私はWordPressを他のアプリケーションのシングルサインオンプロバイダとして使用するプラグインを開発中です。 wp_new_user_notification()によって送信されたEメールに返信することによって、ユーザーが自分のEメールアドレスを確認したことを確認する必要があります。

これまでのところ、私が見つけた最良のアプローチはafter_password_resetアクションにフックしてuser_metadataを追加してEメールが検証されたことを示すことです。これはうまくいきますが、reset_password関数が呼び出されたということだけが本当に私に言っています。

これを行うより良い方法はありますか?

7
Simon Cossar

私はユーザーのEメールを確認するためにいくつかの異なるアプローチを試しました。今のところ、私がやっているのはこれです:

ユーザーが最初に登録するときに、ユーザーのuser_metadata 'email_not_verified'を1に設定します。

add_action( 'user_register', 'sc_user_email_not_verified' );
function sc_user_email_not_verified( $user_id ) {
  update_user_meta( $user_id, 'email_not_verified', 1 );
}

次に、ログインURLに 'email_verification_key'を追加するようにwp_new_user_notification関数をオーバーライドします。そのキーもuser_metadataとして保存します。

function wp_new_user_notification( $user_id, $depreciated = null, $notify = '' ) {

...

$email_verification_key = wp_generate_password( 20, false );
update_user_meta( $user_id, 'email_verification_key', $email_verification_key );

$message = sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n";
$message .= __('To set your password, visit the following address:') . "\r\n\r\n";
$message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&mail_key=$email_verification_key&login=" . rawurlencode($user->user_login), 'login') . ">\r\n\r\n";
$message .= wp_login_url() . "\r\n";

wp_mail($user->user_email, sprintf(__('[%s] Your username and password info'), $blogname), $message);
}

次に、 'validate_password_reset'アクションをフックして、パスワードリセット要求からの電子メール確認キーが保存されたキーと一致することを確認します。キーが一致しない場合は、ユーザーを削除して「emailnotverified」のエラーで登録フォームにリダイレクトします。キーが一致する場合は、 'email_not_verified'メタデータを削除してください。

add_action( 'validate_password_reset', 'sc_verify_user_email', 10, 2 );
function sc_verify_user_email( $errors, $user ) {
    if ( isset( $_REQUEST['mail_key'] ) ) {
        $email_verification_key = $_REQUEST['mail_key'];
        $saved_key              = get_user_meta( $user->ID, 'email_verification_key', true );

        if ( ! ( $email_verification_key === $saved_key ) ) {
            require_once( ABSPATH . 'wp-admin/includes/user.php' );
            wp_delete_user( $user->ID );
            wp_redirect( network_site_url( "wp-login.php?action=register&error=emailnotverified" ) );
            exit;
        } else {
            delete_user_meta( $user->ID, 'email_not_verified' );
        }
    }
}

電子メールが検証されていない場合は、「emailnotverified」エラーが発生したときに登録ページに表示されるメッセージを追加します。

add_filter( 'login_message', 'sc_email_not_verified_message' );
function sc_email_not_verified_message() {
    $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
    $error = isset( $_REQUEST['error'] ) ? $_REQUEST['error'] : '';

    if ( 'register' === $action && 'emailnotverified' === $error ) {
        $message = '<p class="message">' . __( 'Your email address could not be verified. Please try registering again.' ) . '</p>';
        return $message;
    }
}

ユーザーが「email_not_verified」メタデータを持っている場合は、シングルサインオン機能の中で、それらをクライアントアプリケーションにログインしないでください。 (これは、プラグインによって追加された登録フォームを介してユーザーが作成された場合に起こります。)

$current_user = wp_get_current_user();
if ( get_user_meta( $current_user->ID, 'email_not_verified', true ) ) {
    echo( 'Invalid request.' ); // This needs to be changed to a redirect.
    exit;
}

また、 'user-edit'ページにユーザーのメール確認ステータスを表示して上書きするチェックボックスを追加しました。


編集する

validate_password_resetアクションにフックすることはおそらくこれをするための最善の方法ではありません。パスワードがリセットされる前に呼び出されるため、パスワードのリセットプロセスにエラーがあったとしても(たとえば、キーが期限切れまたは無効である場合など)、電子メールは検証されます。

より良い方法はresetpass_formアクションにフックして、 'mail_key'の値を保持するパスワードリセットフォームに隠しフィールドを追加することです。

add_action( 'resetpass_form' 'sc_mail_key_field' );
function sc_mail_key_field() {

    if ( isset( $_REQUEST['mail_key'] ) ) { 

        $mail_key = sanitize_key( wp_unslash( $_REQUEST['mail_key'] ) );
        wp_nonce_field( 'verify_email', 'verify_email_nonce' );
        echo '<input type="hidden" name="mail_key" value="' . esc_attr( $mail_key ) . '" />';
    }
}

保存されたメールキーをafter_password_reset値と照合するために$_POST['mail_key']アクションにフックすることが可能です。

プラグインの例はここにあります: Eメールアドレス検証プラグイン

3
Simon Cossar

私はwp_usermetaテーブルを調べたところ、default_password_nagメタキーに気付きました。

私はチェックし、これは約 - 7年前に #9710 に導入されました。

ユーザーに 自動生成されたパスワード がある場合、その値は1であり、ダッシュボード画面に通知が表示されます。

彼女が最初に登録するとき、default_password_nagは1です、そして彼女がパスワードをリセットするとき、電子メールリンクに続いて、それは0になります。

それがあなたの設定でどんな用途にも使えるならば、あなたはこれをさらに調べることができます。

そうでなければ、カスタムの counter または flag を作成し、それを user meta に格納することができます。例えば。ユーザー作成プロセスにフックし、ユーザーがパスワードをリセットまたはログインしたときにそれを更新します。

2
birgire