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

Node.js Mongoose回调参数顺序异常及Passport OAuth数据存储问题

解决Passport OAuth + Mongoose的用户记录存储问题(修正Promise回调参数顺序)

嘿,我看到你在结合Passport OAuth和Mongoose存储用户记录时,遇到了then()回调参数顺序搞反的坑——把查询结果放到了错误参数的位置,这确实很容易混淆!

问题根源

你搞混了Mongoose传统回调模式和Promise模式的参数顺序:

  • Mongoose回调模式的参数顺序是(err, 查询结果)
  • 但Promise的then()方法,第一个参数是成功回调(接收查询结果),第二个才是错误回调(接收错误信息),这和回调模式的顺序完全相反,很容易写错。

修正后的代码实现(含“存在则忽略,不存在则创建”逻辑)

我更推荐用async/await来写,代码更直观,完全避免参数顺序混乱的问题:

passport.use(new GoogleStrategy({
    clientID: confKeys.googleAuth.client_id,
    clientSecret: confKeys.googleAuth.client_secret,
    callbackURL: confKeys.googleAuth.redirect_uris[0]
}, async (accessToken, refreshToken, profile, done) => {
    try {
        // 先查询数据库中是否已有该用户
        let existingUser = await User.findOne({ googleID: profile.id });
        
        if (existingUser) {
            // 用户已存在,直接通过Passport返回用户信息
            return done(null, existingUser);
        }

        // 用户不存在,创建新记录并存入数据库
        const newUser = await new User({
            googleID: profile.id,
            // 可根据需求添加更多Profile字段,比如昵称、邮箱
            displayName: profile.displayName,
            email: profile.emails?.[0]?.value
        }).save();

        done(null, newUser);
    } catch (error) {
        // 捕获所有数据库操作错误,传递给Passport处理
        done(error);
    }
}));

如果你坚持用Promise的then()写法

一定要牢记参数顺序,正确写法如下(不推荐,可读性不如async/await):

passport.use(new GoogleStrategy({
    clientID: confKeys.googleAuth.client_id,
    clientSecret: confKeys.googleAuth.client_secret,
    callbackURL: confKeys.googleAuth.redirect_uris[0]
}, (accessToken, refreshToken, profile, done) => {
    User.findOne({ googleID: profile.id })
        // 第一个回调是成功拿到查询结果
        .then(user => {
            if (user) return done(null, user);
            // 没有用户则创建新用户,返回创建后的Promise
            return new User({ googleID: profile.id }).save();
        })
        // 接收创建新用户的结果
        .then(newUser => done(null, newUser))
        // 统一捕获所有错误
        .catch(err => done(err));
}));

额外优化建议

为了彻底避免重复创建用户,建议在User模型的googleID字段上设置唯一索引:

const userSchema = new mongoose.Schema({
    googleID: { type: String, unique: true, required: true },
    // 其他字段...
});

内容的提问来源于stack exchange,提问作者ampher911

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:30:36