如何生成一个唯一的id并将其保存到passportJS中的mongoDB?

时间:2016-07-14 00:53:38

标签: node.js mongodb passport.js

我正在使用passportJS,在我的回调中我想进行以下操作。

1)生成随机字符串

2)检查数据库是否存在该ID,如果存在,则重新生成id,直到它是唯一的。

3)保存用户模型(具有唯一ID)。

我尝试编写多个函数,但似乎newUser对象在函数内部未定义!

这是我在我的猫鼬模型中使用的函数。

userSchema.methods.generateVci = function(length, characters){
    var string = '';
    for(var i = length; i > 0; --i){
        string += characters[Math.round(Math.random() * (characters.length - 1))];
    }
    return string;
};

userSchema.statics.validateVci = function(uniquekey){
    this.find({}, function(err,user){
        for(var i = 0; i < user.length; ++i){
            var uservci = user[i].local.vci;
            if(uservci == uniquekey){
                console.log('false');
                return false;
            }
        }
        console.log('true');
      return true;
});
};

passport.use('local-signup', new LocalStrategy({
            // by default, local strategy uses username and password, we will override with email
            usernameField : 'email',
            passwordField : 'password',
            passReqToCallback : true // allows us to pass back the entire request to the callback
        },
        function(req, email, password, done) {
            
            // find a user whose email is the same as the forms email
            // we are checking to see if the user trying to login already exists
            User.findOne({ 'local.email' :  email }, function(err, user) {
                // if there are any errors, return the error
                if (err)
                    return done(err);
                
                // check to see if theres already a user with that email
                if (user) {
                    return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
                } else {





                        var generatedVciKey = newUser.generateVci(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

                        var isvalidvci = User.validateVci(generatedVciKey);

                        if(isvalidvci){
                            var newUser = new User();
                            newUser.local.email    = email;
                            newUser.local.password = newUser.generateHash(password);
                            newUser.local.vci = generatedVciKey;
                        }


                    // save the user
                    newUser.save(function(err) {
                        if (err)
                            throw err;
                        return done(null, newUser);
                    });
                }

            });

        }));

如果你能告诉我一种编写某种递归函数的方法,那就是只有在生成了唯一的(用数据库检查)id时才会保存用户模型。必须一次又一次地重新生成唯一ID,直到它与数据库中的任何其他ID完全唯一。我不知道如何做到这一点似乎在我写一个函数时,passportjs回调中的变量变得不确定。

2 个答案:

答案 0 :(得分:1)

我重写了这个generateVci但是你应该像已经建议的那样使用node-uuid

userSchema.methods.generateVci = function(length, characters) {
  return characters.split('').map(function() {
    var randomKey = Math.round(Math.random() * (characters.length - 1));

    return characters[randomKey];
  }).join('').substring(0, length);
};

你的validateVCI是异步的,所以你必须传递一个回调或其他方式是使用promises

userSchema.statics.validateVci = function(uniquekey, cb){
  this.find({}, function(err, users){
    if (err) {
      return cb(err);
    }

    var isInvalid = users.reduce(function(invalid, user) {
      if (invalid) {
        return true;
      }

      return user.local.vci === uniquekey;
    }, false);

    if (isInvalid) {
      return cb(null, false);
    }

    console.log('true');
    return cb(null, true);
  });
};

你应该在你的数据库中使vci字段唯一... 因此,当您尝试创建具有相同vci的用户时,它将失败

function createUser(email, password, done) {
  var generatedVciKey = newUser.generateVci(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

  User.validateVci(generatedVciKey, function(isInvalid) {
    if (isInvalid) {
      return createUser(email, password, done)
    }

    var newUser = new User();
    newUser.local.email    = email;
    newUser.local.password = newUser.generateHash(password);
    newUser.local.vci = generatedVciKey;

    // save the user, or try again on error
    newUser.save(function(err) {
      if (err) {
        return createUser(email, password, done);
      }

      done(null, newUser);
    });
  });
}

passport.use('local-signup', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
}, function(req, email, password, done) {
    // find a user whose email is the same as the forms email
    // we are checking to see if the user trying to login already exists
    User.findOne({ 'local.email' :  email }, function(err, user) {
            // if there are any errors, return the error
            if (err)
                return done(err);
            if (user) {
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            }

      createUser(email, password, done);
    });
}));

答案 1 :(得分:0)

你真的需要这样做吗?您可以使用node-uuid生成唯一标识符。因此,您将产生非uniqe id可忽略不计的低

的可能性