You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth + Next.js 13.4 + MongoDB用户验证报错求助

解决NextAuth+MongoDB Google登录时的用户名验证错误

问题根源

控制台提示的错误是因为Google返回的用户名称处理后,不符合Mongoose User模型中对username的验证规则:

  • 长度必须在8-20字符之间
  • 不能以_或.开头/结尾
  • 不能包含连续的_或.
  • 必须唯一

当前代码中username: profile.name.replaceAll(' ', '').toLowerCase()的生成逻辑,无法保证满足这些要求(比如短名字处理后长度不足8位)。

修复方案

1. 完善用户名生成与 sanitize 逻辑

在signIn回调中,替换原有的用户名生成代码,确保生成的用户名符合验证规则,同时保证唯一性:

修改app/api/auth/[...nextauth]/route.js中的signIn函数:

async signIn({ account, profile, user, credentials }) {
    try {
        await connectToDB();

        // check if user already exists
        const userExists = await User.findOne({ email: profile.email });

        // if not, create a new document and save user in MongoDB
        if (!userExists) {
            // 生成基础用户名:名字+邮箱前缀,转小写并移除空格
            const namePart = profile.name.replaceAll(' ', '').toLowerCase();
            const emailPart = profile.email.split('@')[0].toLowerCase();
            let baseUsername = `${namePart}${emailPart}`;

            // 清理用户名:去除首尾的_.、替换连续_.为单个_
            baseUsername = baseUsername.replace(/^[_.]+/, '')
                                      .replace(/[_.]+$/, '')
                                      .replace(/[_.]{2,}/g, '_');

            // 调整长度到8-20位
            let username = baseUsername.slice(0, 20);
            if (username.length < 8) {
                // 不足8位时补充随机字母数字
                const randomStr = Math.random().toString(36).substring(2, 8 - username.length + 2);
                username += randomStr;
            }

            // 确保用户名唯一,重复则添加计数器后缀
            let uniqueUsername = username;
            let counter = 1;
            while (await User.findOne({ username: uniqueUsername })) {
                // 保留前17位,加上计数器,确保总长度不超20
                uniqueUsername = `${username.slice(0, 17)}${counter}`;
                counter++;
            }

            await User.create({
                email: profile.email,
                username: uniqueUsername,
                image: profile.picture,
            });
        }

        return true;
    } catch (error) {
        console.log('Error checking if user exists: ', error.message);
        return false;
    }
},

2. 可选:调整验证规则(如果业务允许)

如果不需要严格的8-20长度限制,可以修改User模型中的正则表达式,比如放宽长度到4-20位:

username: {
    type: String,
    required: [true, 'Username is required!'],
    match: [
        /^(?=.{4,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$/,
        'Username invalid, it should contain 4-20 alphanumeric letters and be unique!',
    ],
},

注意:此方案仅适合业务允许放宽规则的场景,优先推荐第一种完善生成逻辑的方案。

验证修复

  1. 重启Next.js服务
  2. 尝试Google登录,此时生成的用户名会自动符合验证规则,不会再触发错误
  3. 查看MongoDB的users集合,确认新用户的username字段符合要求

内容的提问来源于stack exchange,提问作者antonkornilov-ua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:57:07