WooCommerce额外注册字段验证失效,如何拦截垃圾注册?
问题
站点遭遇大量垃圾注册,尝试通过拦截未填写必填字段的注册请求解决,已使用woocommerce_register_post、woocommerce_process_registration_errors和woocommerce_registration_errors钩子添加额外验证逻辑,但未填写必填字段的虚假注册仍能成功提交,甚至出现完全空白的注册账户。疑问如下:
- 这些钩子是否仅返回表单错误而不阻止注册?
- 是否存在其他钩子可以真正阻止账户创建并禁用新账户注册邮件的触发?
使用的代码如下:
function register_validate_custom_fields( $username, $email, $validation_errors ) { // make sure all required fields are present $required_fields = ["email", "billing_first_name", "billing_last_name", "billing_address_1", "billing_city", "billing_state", "billing_postcode"]; foreach ($required_fields as $field) { if (!isset($_POST[$field]) || $_POST[$field] == "") { $validation_errors->add('required_field', __('Required field missing', 'woocommerce')); } } return $validation_errors; } add_action('woocommerce_register_post', 'register_validate_custom_fields', 10, 3); function custom_registration_errors( $validation_error ) { // make sure all required fields are present $required_fields = ["email", "billing_first_name", "billing_last_name", "billing_address_1", "billing_city", "billing_state", "billing_postcode"]; foreach ($required_fields as $field) { if (!isset($_POST[$field]) || empty($_POST[$field])) { $validation_error = new WP_Error( 'required_field', __( 'Required field missing', 'woocommerce' ) ); } } return $validation_error; } add_action( 'woocommerce_process_registration_errors', 'custom_registration_errors' ); function validate_required_fields( $errors, $username, $email ) { // make sure all required fields are present $required_fields = ["email", "billing_first_name", "billing_last_name", "billing_address_1", "billing_city", "billing_state", "billing_postcode"]; foreach ($required_fields as $field) { if (!isset($_POST[$field]) || empty($_POST[$field])) { $errors->add('required_field', __('Required field missing', 'woocommerce')); } } return $errors; } add_filter( 'woocommerce_registration_errors', 'validate_required_fields', 10, 3 );
解决方法
问题根源
你当前的代码存在几个关键问题,导致验证失效:
woocommerce_process_registration_errors钩子处理错误:每次循环都会重新创建WP_Error对象,覆盖之前的错误,若最后一个字段合法,会返回空错误对象,导致验证通过。- 多个钩子重复验证,但逻辑有疏漏:比如
woocommerce_register_post中用$_POST[$field] == ""判断空值,不如empty()严谨;且未提前终止流程,即便添加错误,后续代码仍可能继续执行。
正确的验证实现
不需要同时用三个钩子,woocommerce_registration_errors是最可靠的拦截注册的钩子——只要在这个钩子中添加错误,WooCommerce就会阻止账户创建,且不会发送注册邮件。以下是修正后的代码:
function validate_required_registration_fields( $errors, $username, $email ) { $required_fields = [ 'email' => __( 'Email address', 'woocommerce' ), 'billing_first_name' => __( 'First name', 'woocommerce' ), 'billing_last_name' => __( 'Last name', 'woocommerce' ), 'billing_address_1' => __( 'Street address', 'woocommerce' ), 'billing_city' => __( 'City', 'woocommerce' ), 'billing_state' => __( 'State/County', 'woocommerce' ), 'billing_postcode' => __( 'Postcode', 'woocommerce' ) ]; foreach ( $required_fields as $field_key => $field_label ) { // 检查字段是否存在且不为空(过滤空格) if ( ! isset( $_POST[$field_key] ) || empty( trim( $_POST[$field_key] ) ) ) { $errors->add( "missing_{$field_key}", sprintf( __( '%s is a required field.', 'woocommerce' ), $field_label ) ); } } return $errors; } add_filter( 'woocommerce_registration_errors', 'validate_required_registration_fields', 20, 3 );
代码说明
- 把钩子优先级设为20,确保在默认验证之后执行,覆盖或补充默认规则。
- 为每个必填字段设置对应错误提示,用户能清楚知道哪个字段未填写。
- 使用
trim()过滤空格,避免仅输入空格的情况被判定为合法。 - 只要
$errors对象中存在错误,WooCommerce就会终止注册流程,不会创建账户,也不会发送注册邮件。
额外优化建议
- 可以配合
woocommerce_new_customer_data钩子进一步过滤或修改用户数据,但如果验证已经拦截,这个钩子不会触发。 - 针对垃圾注册,除了字段验证,还可以添加验证码、邮箱验证等机制,提升拦截效果。
内容的提问来源于stack exchange,提问作者brassmookie
相关产品推荐
相关产品推荐

