Nodejs + Passport:如何添加更多用户信息
Nodejs + Passport: How to add more user information
我是 Nodejs 的新手,正在寻找用户凭证管理,我认为 Passport 是一个不错的选择。
但是在Passport的注册策略中,我只看到保存的用户信息是邮箱和密码。
我需要更多用户信息,例如全名、工作、注册时间、最后 activity 时间等
那么我如何在 Passport 中执行此操作?
在您的 Passport.js signup/register 策略中,您应该能够将请求对象作为该函数的第一个参数传入,Passport 将负责将您的请求传递到您的函数中你.
所以您应该能够使用 req.body
对象,以这种方式从您的表单中获取数据并将其存储到您的数据库中。
下面是一个更详细的例子,说明它是如何工作的。
passport.use('signup', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
findOrCreateUser = function(){
// find a user in Mongo with provided username
User.findOne({'username':username},function(err, user) {
// In case of any error return
if (err){
console.log('Error in Signup: ' + err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists');
return done(null, false,
req.flash('message','User Already Exists'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
newUser.firstName = req.body.firstName;
newUser.lastName = req.body.lastName;
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute
// the method in the next tick of the event loop
process.nextTick(findOrCreateUser);
});
);
这里 tutorial 更详细地介绍了它。我确实将 firstName 和 lastName 参数从 params 更改为主体中的变量。但是您可以使用 params 或 body 将该数据放入您的本地策略中。
我发现这样效果更好。 done 在请求、用户名、密码之后但在您希望传递给函数的其他变量之前似乎是关键。如果 done 放在最后则:
events.js:160 throw er; // Unhandled 'error' event TypeError: done is not a function
会被退回。
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done, fname, lname, email, security_question, security_answer) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// 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.username' : username }, 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 username is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.fname = fname;
newUser.local.lname = lname;
newUser.local.username = username;
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.local.security_question = security_question;
newUser.local.security_answer = newUser.generateHash(security_answer);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
当请求 newUser 参数时,其他参数应该像这样从表单正文中请求
newUser.local.fname = req.body.fname
我是 Nodejs 的新手,正在寻找用户凭证管理,我认为 Passport 是一个不错的选择。
但是在Passport的注册策略中,我只看到保存的用户信息是邮箱和密码。
我需要更多用户信息,例如全名、工作、注册时间、最后 activity 时间等
那么我如何在 Passport 中执行此操作?
在您的 Passport.js signup/register 策略中,您应该能够将请求对象作为该函数的第一个参数传入,Passport 将负责将您的请求传递到您的函数中你.
所以您应该能够使用 req.body
对象,以这种方式从您的表单中获取数据并将其存储到您的数据库中。
下面是一个更详细的例子,说明它是如何工作的。
passport.use('signup', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
findOrCreateUser = function(){
// find a user in Mongo with provided username
User.findOne({'username':username},function(err, user) {
// In case of any error return
if (err){
console.log('Error in Signup: ' + err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists');
return done(null, false,
req.flash('message','User Already Exists'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
newUser.firstName = req.body.firstName;
newUser.lastName = req.body.lastName;
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute
// the method in the next tick of the event loop
process.nextTick(findOrCreateUser);
});
);
这里 tutorial 更详细地介绍了它。我确实将 firstName 和 lastName 参数从 params 更改为主体中的变量。但是您可以使用 params 或 body 将该数据放入您的本地策略中。
我发现这样效果更好。 done 在请求、用户名、密码之后但在您希望传递给函数的其他变量之前似乎是关键。如果 done 放在最后则:
events.js:160 throw er; // Unhandled 'error' event TypeError: done is not a function
会被退回。
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done, fname, lname, email, security_question, security_answer) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// 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.username' : username }, 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 username is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.fname = fname;
newUser.local.lname = lname;
newUser.local.username = username;
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.local.security_question = security_question;
newUser.local.security_answer = newUser.generateHash(security_answer);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
当请求 newUser 参数时,其他参数应该像这样从表单正文中请求
newUser.local.fname = req.body.fname