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