Verify Email Addresses of New Users
Sends new members a confirmation link and blocks them from logging in until they click it, which keeps fake and mistyped email addresses out.
Opens WPIDE on
Code
// Hours a verification link stays valid.
$wpide_verify_hours = 48;
$wpide_send_verify = function ( $user_id ) {
$user = get_userdata( $user_id );
$token = wp_generate_password( 32, false );
update_user_meta( $user_id, 'wpide_email_verify', array( 'hash' => wp_hash( $token ), 'time' => time() ) );
$link = add_query_arg( array( 'wpide_verify' => $user_id, 'key' => $token ), wp_login_url() );
wp_mail(
$user->user_email,
sprintf( '[%s] Please confirm your email address', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) ),
sprintf( "Hi %s,\n\nPlease confirm your email address to activate your account:\n%s\n\nIf you did not sign up, you can ignore this email.", $user->display_name, $link )
);
};
add_action( 'user_register', function ( $user_id ) use ( $wpide_send_verify ) {
// Skip accounts made by administrators, WP-CLI or scheduled tasks.
if ( current_user_can( 'create_users' ) || ( defined( 'WP_CLI' ) && WP_CLI ) || wp_doing_cron() ) {
return;
}
$wpide_send_verify( $user_id );
}, 20 );
add_filter( 'authenticate', function ( $user ) {
if ( $user instanceof WP_User && get_user_meta( $user->ID, 'wpide_email_verify', true ) ) {
return new WP_Error( 'wpide_unverified', '<strong>Please confirm your email address.</strong> We sent you a link when you signed up.' );
}
return $user;
}, 60 );
add_action( 'login_init', function () use ( $wpide_verify_hours, $wpide_send_verify ) {
if ( empty( $_GET['wpide_verify'] ) || empty( $_GET['key'] ) ) {
return;
}
$user_id = absint( $_GET['wpide_verify'] );
$data = get_user_meta( $user_id, 'wpide_email_verify', true );
$key = sanitize_text_field( wp_unslash( $_GET['key'] ) );
if ( ! is_array( $data ) ) {
wp_safe_redirect( add_query_arg( 'wpide_verified', 'already', wp_login_url() ) );
exit;
}
if ( time() - (int) $data['time'] > $wpide_verify_hours * HOUR_IN_SECONDS ) {
$wpide_send_verify( $user_id );
wp_safe_redirect( add_query_arg( 'wpide_verified', 'expired', wp_login_url() ) );
exit;
}
if ( hash_equals( $data['hash'], wp_hash( $key ) ) ) {
delete_user_meta( $user_id, 'wpide_email_verify' );
wp_safe_redirect( add_query_arg( 'wpide_verified', 'yes', wp_login_url() ) );
exit;
}
} );
add_filter( 'login_message', function ( $message ) {
$state = isset( $_GET['wpide_verified'] ) ? sanitize_key( $_GET['wpide_verified'] ) : '';
$messages = array(
'yes' => 'Thanks, your email address is confirmed. You can log in now.',
'already' => 'This link was already used. You can log in.',
'expired' => 'That link had expired, so we have emailed you a new one.',
);
if ( isset( $messages[ $state ] ) ) {
$message .= '<p class="message">' . esc_html( $messages[ $state ] ) . '</p>';
}
return $message;
} );
Notes
Most useful when members choose their own password at sign-up; accounts created by administrators and users who existed before activation are treated as verified.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.