在数据库中查询护照配置中的两个字段

query the database for two fields in passport configuration

我在注册时有一个用户名字段和一个电子邮件字段,我想在将用户添加到数据库之前检查它们是否存在。大多数护照示例只查找一个字段,如用户名,我不知道如何查找 2。如果我执行下面的操作,用户输入现有用户名,但输入不存在的电子邮件,它将通过,如果用户输入一个现有的电子邮件,但输入一个不存在的用户名,因为它们不是用户名。

我知道为什么会这样。我只是想不出如何将这两个查询放在一起,所以只有在它看到没有用户名和/或没有电子邮件后才会保存它。为了更清楚,用户名和电子邮件不应重复。

我在想也许可以在 else 语句中设置一个变量,表示可以保存用户,稍后在代码中检查是否有 2 个这些变量,如果有这些变量则保存,但我不知道该怎么做。我认为这很难,因为查询是异步的。我希望我能用那种方法。

我将如何处理连接闪存消息?

passport.use("local-signup", new LocalStrategy({
    usernameField : "email",
    passwordField : "password",
    passReqToCallback : true
},
    function(req, email, password, done){
        User.findOne({"email" : email}, function(err, user){
            if(err) return done(err);
            if(user){
                return done(null, false, req.flash("signupMessage", "That email is already taken"))
            }else{
                var newUser = new User();
                newUser.username = req.body.username;
                newUser.password = password;
                newUser.email = req.body.email;

                newUser.save(function(err, doc){
                    if(err) throw err;
                    console.log("doc", " " , doc)
                    return done(null, newUser);
                })
            }
        })
        console.log("username " + req.body.username)
        User.findOne({"username" : req.body.username}, function(err, user){
            if(err) return done(err);
            if(user){
                return done(null, false, req.flash("signupMessage", "that username is taken"))
            }else{
                var newUser = new User();
                newUser.username = req.body.username;
                newUser.password = password;
                newUser.email = req.body.email;

                newUser.save(function(err, doc){
                    if(err) throw err;
                    console.log("doc", " " , doc)
                    return done(null, newUser);
                })
            }
        })
    }
))

有很多方法可以做到这一点。

例如,您可以按照promise的方式进行;您可以同时执行和异步调用以检查用户名和电子邮件,如果两个调用 return 一个 OK 结果,然后您继续插入。

参见:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

既然你上面已经有了一些代码,我将以异步方式逐步执行传统的嵌套。

我在下面得到的是 - 首先我调用 User.findOne() 来检查电子邮件,如果该值是唯一的,然后继续使用 User.findOne() 再次检查用户名。

代码仅在第二次 User.findOne() 调用报告正常时才继续插入用户。

注意: 虽然此逻辑有效,但如果您嵌套太多调用,您将进入 Javascript 社区通常描述为 callback hell.

passport.use("local-signup", new LocalStrategy({
      usernameField : "email",
      passwordField : "password",
      passReqToCallback : true
    },
    function(req, email, password, done){
      // register user only if the email and username is unique
      // Step 1: Check email
      User.findOne({"email" : email}, function(err, user){
        if(err) return done(err);
        if(user){
          return done(null, false, req.flash("signupMessage", "That email is already taken"))
        } else {
          // Email is fine.
          // Step 2: Check username
          User.findOne({"username" : req.body.username}, function(err, user){
            if(err) return done(err);
            if(user){
              return done(null, false, req.flash("signupMessage", "that username is taken"))
            }else{
              // User name is fine too
              // Step 3: Create user
              var newUser = new User();
              newUser.username = req.body.username;
              newUser.password = password;
              newUser.email = req.body.email;

              newUser.save(function(err, doc){
                if(err) throw err;
                // User created
                console.log("doc", " " , doc);
                return done(null, newUser);
              });
            }
          });
        }
      });
    };