WooCommerce 密码重置限制为仅支持邮箱验证

本文介绍如何在 WooCommerce 中强制用户只能通过邮箱(而非用户名)重置密码,通过 WordPress 原生钩子 lostpassword_errors 和 WooCommerce 兼容钩子 lostpassword_post 实现输入校验与错误提示。

本文介绍如何在 WooCommerce 中强制用户只能通过邮箱(而非用户名)重置密码,通过 WordPress 原生钩子 `lostpassword_errors` 和 WooCommerce 兼容钩子 `lostpassword_post` 实现输入校验与错误提示。

在默认的 WordPress 及 WooCommerce 密码找回流程中,用户既可输入用户名也可输入邮箱来触发密码重置。但出于安全与用户体验一致性考虑,许多站点希望仅允许邮箱作为唯一凭证——即:若用户输入不包含 @ 符号,则直接报错,拒绝继续处理。

实现该需求的核心在于拦截密码重置前的表单验证逻辑。WordPress 在 wp-includes/user.php 第 2930 行提供了关键过滤器:

$errors = apply_filters( 'lostpassword_errors', $errors, $user_data );

该钩子在用户提交「忘记密码」表单后、系统查询用户前执行,是介入校验逻辑的理想位置。

✅ 推荐方案:使用 lostpassword_errors 钩子(兼容 WordPress + WooCommerce)

将以下代码添加至主题的 functions.php 文件或专用插件中:

add_filter( 'lostpassword_errors', 'wc_reset_password_by_email_only', 20, 2 );

function wc_reset_password_by_email_only( $errors, $user_data ) {
    $user_login = ! empty( $_POST['user_login'] ) ? wp_unslash( $_POST['user_login'] ) : '';

    if ( empty( $user_login ) ) {
        $errors->add( 'empty_username', __( '<strong>错误</strong>:请输入邮箱地址。', 'textdomain' ) );
    } elseif ( strpos( $user_login, '@' ) === false ) {
        $errors->add( 'invalid_input', __( '<strong>错误</strong>:密码重置仅支持邮箱地址,请输入有效的邮箱。', 'textdomain' ) );
    } else {
        // 验证邮箱是否存在
        $user_data = get_user_by( 'email', trim( $user_login ) );
        if ( ! $user_data ) {
            $errors->add( 'invalid_email', __( '<strong>错误</strong>:未找到与此邮箱关联的账户。', 'textdomain' ) );
        }
    }

    return $errors;
}

说明

  • 使用 strpos(..., '@') === false 精确判断是否为邮箱(避免误判含 @ 的用户名);
  • wp_unslash() 防止反斜杠干扰;
  • 错误消息已本地化(支持翻译),请根据主题/插件替换 'textdomain';
  • 此方案适用于所有标准密码重置入口(包括 /wp-login.php?action=lostpassword 和 WooCommerce 的 [woocommerce_my_account] 表单)。

⚠️ 注意事项

✅ 效果验证

部署后测试以下场景:

通过这一简洁可靠的钩子方案,你可在不修改 WooCommerce 核心文件的前提下,安全、可维护地实现「邮箱专属密码重置」策略。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。