Wie kann ich sicher sein, dass ein Benutzer seine E-Mail-Adresse nach der Registrierung überprüft hat?

7

Ich arbeite an einem Plugin, das WordPress als Single Sign On-Anbieter für eine andere Anwendung verwendet. Ich muss sicher sein, dass der Benutzer seine E-Mail-Adresse überprüft hat, indem er auf die von gesendete E-Mail antwortet wp_new_user_notification().

Bisher ist der beste Ansatz, den ich gefunden habe, sich in die after_password_resetAktion einzumischen und user_metadata hinzuzufügen, um anzuzeigen, dass die E-Mail überprüft wurde. Das funktioniert, aber alles, was mir wirklich sagt, ist, dass die reset_passwordFunktion aufgerufen wurde.

Gibt es einen besseren Weg, dies zu tun?

Simon Cossar
quelle
2
Vielleicht empty( get_userdata( $user_id )->user_activation_key )?
Samuel Elh
Es sieht so aus, als würde das immer noch nur anzeigen, dass reset_passwordaufgerufen wurde. ( reset_passwordruft an wp_set_password, dort wird der Aktivierungsschlüssel auf '' gesetzt.)
Simon Cossar
1
Was ist mit einem benutzerdefinierten Zähler für das Zurücksetzen von Kennwörtern für jeden Benutzer, der im Benutzer-Meta gespeichert ist?
Birgire

Antworten:

3

Ich habe verschiedene Ansätze zum Überprüfen der E-Mail-Adresse des Benutzers ausprobiert. Im Moment mache ich Folgendes:

Wenn sich ein Benutzer zum ersten Mal registriert, setzen Sie die Benutzermetadaten 'email_not_verified' des Benutzers auf 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 );
}

Überschreiben Sie dann die wp_new_user_notificationFunktion, damit der Anmelde-URL ein 'email_verification_key' hinzugefügt wird. Dieser Schlüssel wird auch als user_metadata gespeichert.

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

Schließen Sie dann die Aktion 'validate_password_reset' an, um zu überprüfen, ob der E-Mail-Bestätigungsschlüssel aus der Anforderung zum Zurücksetzen des Kennworts mit dem gespeicherten Schlüssel übereinstimmt. Wenn die Schlüssel nicht übereinstimmen, löschen Sie den Benutzer und leiten Sie ihn mit dem Fehler "emailnotverified" zurück zum Registrierungsformular. Wenn die Schlüssel übereinstimmen, löschen Sie die Metadaten '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' );
        }
    }
}

Wenn die E-Mail nicht überprüft wurde, fügen Sie eine Nachricht hinzu, die auf der Registrierungsseite angezeigt wird, wenn der Fehler "E-Mail nicht bestätigt" auftritt.

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

Wenn der Benutzer innerhalb der Single Sign On-Funktion über die Metadaten 'email_not_verified' verfügt, melden Sie diese nicht bei der Clientanwendung an. (Dies kann passieren, wenn der Benutzer über ein Registrierungsformular erstellt wurde, das von einem Plugin hinzugefügt wurde.)

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

Ich habe auch ein Kontrollkästchen hinzugefügt, um den E-Mail-Bestätigungsstatus des Benutzers auf der Seite "Benutzer bearbeiten" anzuzeigen und zu überschreiben.


Bearbeiten:

Sich in die validate_password_resetAction einzumischen ist wahrscheinlich nicht der beste Weg, dies zu tun. Es wird aufgerufen, bevor das Kennwort zurückgesetzt wird, sodass die E-Mail auch dann überprüft wird, wenn beim Zurücksetzen des Kennworts Fehler auftreten (z. B. wenn der Schlüssel abgelaufen oder ungültig ist).

Ein besserer Ansatz scheint darin zu bestehen, sich in die resetpass_formAktion einzumischen und dem Formular zum Zurücksetzen des Kennworts ein verstecktes Feld hinzuzufügen, das den Wert des 'mail_key' enthält:

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

Es ist dann möglich, sich an der after_password_resetAktion zu beteiligen, um den gespeicherten E-Mail-Schlüssel anhand des $_POST['mail_key']Werts zu überprüfen .

Ein Beispiel-Plugin finden Sie hier: Plugin zur Überprüfung der E-Mail-Adresse

Simon Cossar
quelle
1
Vielen Dank für das Teilen, was für Sie funktioniert hat. PS: Ich würde vorschlagen , benutzerdefinierte Metadaten prefixing mit anderen Plugins möglich Namenskollision zu vermeiden , und es wird empfohlen , hinzufügen exit;nach wp_redirect().
Birgire
Danke, bearbeiten ich den Code auf hier hinzufügen exit;nach wp_redirect(). In dem Code, den ich tatsächlich verwende, lösche ich keinen Benutzer mehr, wenn sein 'mail_key' nicht mit dem gespeicherten Schlüssel übereinstimmt. Wenn die Schlüssel nicht übereinstimmen, wird der Benutzer erstellt, jedoch mit dem Flag "email_not_verified".
Simon Cossar
2

Ich warf einen Blick in die wp_usermetaTabelle und bemerkte den default_password_nagMetaschlüssel.

Ich habe nachgesehen und dies wurde vor ungefähr 7 Jahren in # 9710 eingeführt.

Wenn der Benutzer ein automatisch generiertes Kennwort hat, ist der Wert 1 und er wird auf dem Dashboard-Bildschirm angezeigt.

Wenn sie sich zum ersten Mal registriert, default_password_nagist 1 und wenn sie das Passwort über den E-Mail-Link zurücksetzt, wird es 0.

Sie können dies genauer untersuchen, wenn es in Ihrem Setup von Nutzen sein kann.

Andernfalls könnte man einen benutzerdefinierten Zähler oder ein Flag erstellen und im Benutzer-Meta speichern . Binden Sie sich beispielsweise in den Benutzererstellungsprozess ein und aktualisieren Sie ihn dann, wenn der Benutzer das Kennwort zurücksetzt oder sich anmeldet.

Birgire
quelle
Das Problem ist, dass ein Plugin das Zurücksetzen des Kennworts ermöglichen kann, ohne dass der Benutzer auf eine E-Mail antwortet, um es zurückzusetzen. WooCommerce tut dies, wenn Sie "Registrierung aktivieren" auswählen. Möglicherweise ist es gut genug zu wissen, dass das Passwort zurückgesetzt wurde und dass das Zurücksetzen von durchgeführt wurde wp-login.php.
Simon Cossar
Ja, Sie haben Recht, Plugins können den Status beeinflussen, z. B. durch benutzerdefinierte Anmelde- / Rücksetzformulare. In diesem Fall ist höchstwahrscheinlich ein benutzerdefinierter Zähler / eine benutzerdefinierte Flagge besser. Der Extremfall wäre ein Plugin mit Benutzererstellung und Zurücksetzen des Passworts durch benutzerdefinierte SQL-Abfragen ;-) @SimonCossar
Birgire