web-dev-qa-db-fra.com

Comment puis-je être certain qu'un utilisateur a vérifié son courrier électronique après son inscription?

Je travaille sur un plugin qui utilise WordPress en tant que fournisseur Single Sign On pour une autre application. Je dois être certain que l'utilisateur a vérifié son adresse électronique en répondant au courrier électronique envoyé par wp_new_user_notification().

Jusqu'à présent, la meilleure approche que j'ai trouvée consiste à se connecter à l'action after_password_reset et à ajouter user_metadata pour indiquer que le courrier électronique est vérifié. Cela fonctionne, mais tout ce que ça me dit, c'est que la fonction reset_password a été appelée.

Y a-t-il une meilleure manière de faire cela?

7
Simon Cossar

J'ai essayé différentes méthodes pour vérifier le courrier électronique de l'utilisateur. Pour le moment, je fais ceci:

Lorsqu'un utilisateur s'enregistre pour la première fois, définissez le paramètre user_metadata 'email_not_verified' sur 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 );
}

Ensuite, remplacez la fonction wp_new_user_notification pour qu’elle ajoute une 'clé email_verification_' à l’URL de connexion. Il enregistre également cette clé sous le nom 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);
}

Ensuite, connectez-vous à l'action 'validate_password_reset' pour vérifier que la clé de vérification de l'e-mail de la demande de réinitialisation du mot de passe correspond à la clé enregistrée. Si les clés ne correspondent pas, supprimez l'utilisateur et redirigez-les vers le formulaire d'inscription avec une erreur 'emailnotverified'. Si les clés correspondent, supprimez les métadonnées "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' );
        }
    }
}

Si l'e-mail n'est pas vérifié, ajoutez un message qui sera affiché sur la page d'inscription en cas d'erreur "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;
    }
}

Dans la fonction de connexion unique, si l'utilisateur dispose des métadonnées "email_not_verified", ne les connectez pas à l'application cliente. (Cela peut arriver si l'utilisateur a été créé via un formulaire d'inscription ajouté par un plugin.)

$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;
}

J'ai également ajouté une case à cocher pour afficher et remplacer le statut de vérification du courrier électronique de l'utilisateur sur la page "modification de l'utilisateur".


Modifier:

Se connecter à l'action validate_password_reset n'est probablement pas la meilleure façon de procéder. Il est appelé avant la réinitialisation du mot de passe. L'e-mail sera donc vérifié même s'il y a des erreurs dans le processus de réinitialisation du mot de passe (par exemple, si la clé est expirée ou invalide.)

Une meilleure approche semble consister à s’associer à l’action resetpass_form et à ajouter un champ masqué au formulaire de réinitialisation du mot de passe contenant la valeur de la 'clé_mail':

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 ) . '" />';
    }
}

Il est ensuite possible de se connecter à l'action after_password_reset pour vérifier la clé de courrier enregistrée par rapport à la valeur $_POST['mail_key'].

Vous trouverez un exemple de plugin ici: plugin de vérification d'adresse e-mail

3
Simon Cossar

J'ai jeté un coup d'œil dans la table wp_usermeta et remarqué la clé méta default_password_nag.

J'ai vérifié et cela a été introduit dans # 9710 il y a environ 7 ans.

Si l'utilisateur a un mot de passe généré automatiquement , sa valeur est égale à 1 et un avis s'affiche sur l'écran du tableau de bord.

Lorsqu’elle s’inscrit pour la première fois, default_password_nag est égal à 1 et lorsqu’elle réinitialise le mot de passe en suivant le lien du courrier électronique, il devient 0.

Vous pouvez approfondir cette question si cela peut vous être utile.

Sinon, on pourrait créer un compteur ou indicateur personnalisé et le stocker dans la méta utilisateur meta . Par exemple. Connectez-vous au processus de création de l'utilisateur, puis mettez-le à jour lorsque l'utilisateur réinitialise le mot de passe ou se connecte.

2
birgire