我正在开发一个插件,该插件使用 WordPress 作为另一个应用程序的单点登录提供程序。 我需要确定用户已经通过回复发送的电子邮件来验证他们的电子邮件地址 wp_new_user_notification()
.
到目前为止,我发现的最好方法是挂接到 after_password_reset
操作并添加 user_metadata 以指示电子邮件已通过验证。 这行得通,但它真正告诉我的是 reset_password
函数已被调用。
有一个更好的方法吗?
我尝试了几种不同的方法来验证用户的电子邮件。 现在,我正在做的是:
当用户首次注册时,将用户的 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 );
}
然后,覆盖 wp_new_user_notification
功能,以便它向登录网址添加“email_verification_key”。 它还将该密钥保存为 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;
}
我还在“用户编辑”页面上添加了一个复选框来显示和覆盖用户的电子邮件验证状态。
编辑:
钩入 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']
价值。
可以在这里找到一个示例插件:电子邮件地址验证插件
我看了一下 wp_usermeta
表并注意到 default_password_nag
元键。
我检查了一下,这是大约 7 年前在 #9710 中介绍的。
如果用户有 自动生成的密码 那么它的值为 1,她将在仪表板屏幕上显示一条通知。
她第一次注册时, default_password_nag
是 1,当她重设密码时,按照电子邮件链接,密码变为 0。
如果它在您的设置中有任何用处,您可以进一步研究。

否则可以创建自定义 柜台 或者 旗帜 并将其存储在 用户元. 例如挂钩到用户创建过程,然后在用户重置密码或登录时更新它。
