在PassportJS中使用多个本地策略

我正在尝试与PassportJS一起使用多个LOCAL策略。 我没有尝试使用本地,Facebook和Gmail等我有两组用户存储在单独的对象,我想使用本地策略来validation两者。 就目前而言,我不能使用相同的本地策略,因为它们具有不同的对象属性,这使我查询了不同的对象。 有没有办法做到这一点? 或任何build议,将不胜感激。

我不认为这是可能的,因为据我所知,当第一个策略失败时,需要一些“分手”的方法,我不相信这是可能的。

但是,您可能可以使用一个本地策略,并尝试使用这两种方法validation传入的数据。

作为一个简单的例子(使用Mongoose作为示例数据库):

passport.use(new LocalStrategy(function(username, password, done) { Model1.findOne({ username : username }, function(err, user) { // first method succeeded? if (!err && user && passwordMatches(...)) { return done(null, user); } // no, try second method: Model2.findOne({ name : username }, function(err, user) { // second method succeeded? if (! err && user && passwordMatches(...)) { return done(null, user); } // fail! done(new Error('invalid user or password')); }); }); })); 

对于序列化/反序列化,您可能需要在user对象中存储一些属性,这些属性用于表示反序列化用户所需的模型。

你可以命名你的本地策略来分开它们。

 // use two LocalStrategies, registered under user and sponsor names // add other strategies for more authentication flexibility passport.use('user-local', new LocalStrategy({ usernameField: 'email', passwordField: 'password' // this is the virtual field on the model }, function(email, password, done) { User.findOne({ email: email }, function(err, user) { if (err) return done(err); if (!user) { return done(null, false, { message: 'This email is not registered.' }); } if (!user.authenticate(password)) { return done(null, false, { message: 'This password is not correct.' }); } return done(null, user); }); } )); // add other strategies for more authentication flexibility passport.use('sponsor-local', new LocalStrategy({ usernameField: 'username', passwordField: 'password' // this is the virtual field on the model }, function(username, password, done) { Sponsor.findOne({ 'primaryContact.username': username }, function(err, sponsor) { if (err) return done(err); if (!sponsor) { return done(null, false, { message: 'This email/username is not registered.' }); } if (!sponsor.authenticate(password)) { return done(null, false, { message: 'This password is not correct.' }); } return done(null, sponsor); }); } )); 

后来的控制器代码通过名称引用它们。

 /** * User Login */ exports.loginUser = function (req, res, next) { passport.authenticate('local-user', function(err, user, info) { var error = err || info; if (error) return res.json(401, error); req.logIn(user, function(err) { if (err) return res.send(err); res.json(req.user.userInfo); }); })(req, res, next); }; /** * Sponsor Login */ exports.loginSponsor = function (req, res, next) { passport.authenticate('local-sponsor', function(err, sponsor, info) { var error = err || info; if (error) return res.json(401, error); req.logIn(sponsor, function(err) { if (err) return res.send(err); res.json(req.sponsor.profile); }); })(req, res, next); }; 

稍后当需要序列化你的用户时,你可能想要做这样的事情。

 // serialize passport.serializeUser(function(user, done) { if (isUser(user)) { // serialize user } else if (isSponsor(user)) { // serialize company } });