WordPress 注册一直提示“用户名包含无效字符”?我排查到最后,竟是一个英文逗号

今天给壹导航处理用户注册问题时,我碰到一个看起来很普通、实际却相当隐蔽的故障:用户明明只输入了数字,系统却一直提示“此用户名包含无效字符,只能使用字母数字下划线”。更离谱的是,换成纯字母、字母加数字、带下划线的用户名,结果依然完全一样。

我前后检查了主题、子主题、自定义字体、登录跳转代码、缓存和验证码,最后才发现真正的原因不是用户名,也不是 WordPress,而是“禁止的昵称关键词”末尾多了一个英文逗号

故障现象:正常用户名全部提示无效

最开始测试注册时,我使用的是一个六位纯数字用户名。按页面提示,用户名允许使用字母、数字和下划线,理论上不应该报错,但提交后右下角仍然出现了无效字符提示。

壹导航注册时纯数字用户名提示包含无效字符的已打码截图
纯数字用户名仍被提示包含无效字符,截图中的邮箱和验证码已经打码。

为了避免被单个测试账号误导,我又分别测试了以下几种格式:

  • 纯数字:654321
  • 纯字母:abcde
  • 字母和数字:a1234
  • 字母、数字和下划线:abc_123

这几种写法全部返回相同提示,说明问题不是某个字符真的不合法,而是校验流程把所有用户名都拦截了。

我一开始排查了哪些方向

1. 怀疑自定义字体影响输入

网站使用了自定义字体,并且通过 CSS 同时应用到按钮和输入框。我一度怀疑数字在显示时被替换成了特殊字符。但字体只能改变文字的显示效果,不会改变提交给服务器的原始表单值,因此很快排除了这个方向。

2. 检查顶部和底部自定义脚本

站内有用于登录后返回原页面、自动刷新登录状态的 JavaScript。我逐段检查后发现,这些代码只处理 user_login 登录动作和页面跳转,并不修改注册表单中的用户名,也不会参与 PHP 后端校验。

3. 切换父主题和子主题

我又在父主题与子主题之间切换测试,问题依然存在。由此可以判断,故障更接近 OneNav 的公共注册逻辑或某项后台配置,而不是页面样式。

4. 绕过页面,直接请求注册接口

为了彻底排除浏览器、字体和前端脚本,我直接向 WordPress 的 admin-ajax.php 提交与注册表单相同的数据。多个合法用户名都得到下面这段返回:

{"status":2,"msg":"此用户名包含无效字符,只能使用字母数字下划线!"}

这一步非常关键:它证明错误来自服务器端,和浏览器怎么显示输入内容无关。

继续做对照:WordPress 用户系统其实是正常的

接下来,我通过 WordPress 官方用户接口创建了一个临时订阅者。账号创建成功,随后也正常删除。这说明数据库写入、WordPress 用户表以及基础的 sanitize_user() 清洗功能都没有问题。

也就是说,真正出错的是 OneNav 自己注册回调中的额外判断。

定位代码:两个条件共用了一条错误提示

在网站文件中搜索错误提示文字后,我找到了注册处理文件中的判断:

elseif (
    ! validate_username($username)
    || is_disable_username($username)
) {
    // 返回“用户名包含无效字符”
}

validate_username() 是 WordPress 的用户名验证函数,而 is_disable_username() 是主题增加的“禁止昵称关键词”检查。因为两个条件共用同一句提示,所以页面只告诉我“字符无效”,并没有告诉我其实是禁用关键词出了问题。

最终原因:关键词结尾多了一个英文逗号

问题最终出在禁止昵称关键词的设置上。原来的内容结尾多了一个英文逗号,结构类似这样:

admin,administrator,root,管理员,

主题会使用 preg_split() 按逗号、空格和换行拆分关键词。末尾这个多余的英文逗号会再拆出一个空字符串,实际效果相当于:

admin
administrator
root
管理员
空关键词

接着,主题用下面的逻辑逐个检查:

foreach ($disable_reg_keywords as $keyword) {
    if (stristr($name, $keyword) || $keyword == $name) {
        return true;
    }
}

在 PHP 8 中,stristr() 允许使用空字符串作为要查找的内容。任何用户名都“包含”这个空关键词,因此循环永远返回 true,最终表现为所有用户名都不合法

解决方案一:删除末尾逗号

最直接的修复方法,是进入主题设置中的禁止昵称关键词配置,删除结尾多余的英文逗号、中文逗号、空格和空白行。正确写法例如:

admin,administrator,root,管理员

重点是最后一个关键词后面不要继续添加逗号。

解决方案二:从代码层过滤空关键词

仅修改后台设置可以立即恢复注册,但为了避免以后再次因为空行或逗号触发同样的问题,我把主题中的函数改成了更稳妥的写法:

function is_disable_username($name)
{
    $raw_keywords = trim(
        (string) io_get_option('user_nickname_stint', '')
    );

    if ($raw_keywords === '' || $name === '') {
        return false;
    }

    $keywords = preg_split(
        '/[,,\s]+/u',
        $raw_keywords,
        -1,
        PREG_SPLIT_NO_EMPTY
    );

    if (empty($keywords)) {
        return false;
    }

    foreach ($keywords as $keyword) {
        $keyword = trim($keyword);

        if (
            $keyword !== '' &&
            stripos($name, $keyword) !== false
        ) {
            return true;
        }
    }

    return false;
}

这里最关键的是 PREG_SPLIT_NO_EMPTY$keyword !== '':前者在拆分时丢弃空项目,后者在匹配前再做一次保险。

如果直接修改的是父主题文件,主题升级后可能被覆盖。建议记录修改位置、提交给主题作者,或在每次升级后检查这一修复是否已经被官方合并。

修复后的验证步骤

  1. 保存禁止昵称关键词,确认末尾没有逗号或空行。
  2. 清除 WordPress Redis 对象缓存及 CDN 页面缓存。
  3. 分别测试纯字母、字母数字和下划线用户名。
  4. 确认注册流程能够继续进入邮箱验证码或滑动验证阶段。
  5. 检查真正需要禁止的关键词仍然能够正常拦截。

这次排查给我的提醒

这次故障最容易误导人的地方,是页面提示与真实原因并不完全一致。提示说“字符无效”,实际却是禁用昵称关键词匹配到了一个空字符串。如果只盯着输入框、字体或用户名格式,很容易反复绕圈。

以后遇到类似问题,我会优先做三件事:用多组输入确认规律、绕过前端直接测试接口、搜索错误提示定位后端判断。很多看起来很大的故障,最后可能真的只是一个不起眼的英文逗号。

最终结论:壹导航这次所有用户名都被判定不合法,是因为“禁止的昵称关键词”结尾多了一个英文逗号。删除逗号并过滤空关键词后,注册功能恢复正常。

你认为这个网站怎么样?

0.0 / 5
-位网友评分
-
-
-
-
-
© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...