node.js - nodejs - Utilice mĂșltiples estrategias locales en PassportJS
passport js tutorial (2)
Estoy tratando de usar múltiples estrategias LOCALES con PassportJS. No estoy tratando de usar local, facebook y gmail, etc. Tengo dos conjuntos de usuarios almacenados en objetos separados y quiero usar una estrategia local para autenticar ambos. Tal como está, no puedo usar la misma estrategia local para ambos porque tienen propiedades de objeto diferentes que me hacen consultar objetos diferentes. ¿Hay alguna manera de hacer esto? O cualquier sugerencia sobre esto sería muy apreciada.
No creo que sea posible, porque, por lo que veo, se necesita algún método para "entregar" una solicitud a la segunda estrategia cuando la primera falla, y no creo que sea posible.
Pero es posible que pueda usar una estrategia local y solo intente autenticar los datos entrantes utilizando ambos métodos.
Como ejemplo simple (usando Mongoose como una base de datos de ejemplo):
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''));
});
});
}));
Para la serialización / deserialización, es posible que necesite almacenar alguna propiedad en el objeto de user
que pase para indicar qué modelo se requiere para deserializar al usuario.
Puede nombrar sus estrategias locales para separarlos.
// 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);
});
}
));
Código de controlador más tarde se refieren a ellos por su nombre.
/**
* 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);
};
Más adelante, cuando llegue el momento de serializar a su usuario, es posible que desee hacer algo como esto.
// serialize
passport.serializeUser(function(user, done) {
if (isUser(user)) {
// serialize user
} else if (isSponsor(user)) {
// serialize company
}
});