我正在使用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回调中的变量变得不确定。
答案 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可忽略不计的低
的可能性