node.js - tutorial - Nodejs Passport autentica la devolución de llamada que no se llama
passport local (3)
Lo estás entendiendo perfectamente, y está funcionando como es debido.
Si se produce algún error, Passport inmediatamente next()
con ese error. Puede usar el middleware de manejo de errores (detalles: http://expressjs.com/guide/error-handling.html ) si quiere manejar ese error de una manera personalizada.
Las devoluciones de llamada personalizadas se utilizan principalmente para tratar el éxito o el fracaso de la autenticación ( user
== false
). Los errores, como la conectividad de la base de datos, etc., no se devuelven a la devolución de llamada, en favor del middleware de manejo de errores descrito anteriormente. He considerado cambiar esto, pero no he encontrado una razón convincente para hacerlo. Pero, si tiene un caso de uso que no está cubierto por lo anterior, hágamelo saber.
Usando Nodejs Passport, estaba probando qué sucede cuando ocurre una condición de error usando el siguiente código:
passport.use(new LocalStrategy(
function(username, password, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
findByUsername(username, function(err, user) {
console.log(''in auth function'');
return done(''errortest'');
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: ''Unknown user '' + username });
}
if (user.password != password) {
return done(null, false, { message: ''Invalid password'' });
}
return done(null, user);
})
});
}
));
app.get(''/logintest'', function(req, res, next) {
console.log(''before authenticate'');
passport.authenticate(''local'', function(err, user, info) {
console.log(''authenticate callback'');
if (err) { return res.send({''status'':''err'',''message'':err.message}); }
if (!user) { return res.send({''status'':''fail'',''message'':info.message}); }
req.logIn(user, function(err) {
if (err) { return res.send({''status'':''err'',''message'':err.message}); }
return res.send({''status'':''ok''});
});
})(req, res, next);
});
Usando la ruta / logintest? Username = bob & password = s esperaba ver en la consola, "antes de autenticar" luego "en auth function" luego "autenticar callback" pero solo muestra las dos primeras seguidas de "errortest" y "errortest "se muestra en el navegador.
También intenté return done({''message'':''test''});
y "[objeto Objeto]" se mostró en la consola y en el navegador.
¿Esto no funciona correctamente o me estoy perdiendo algo?
EDITAR: De acuerdo con la respuesta de Jared Hanson, agregar esta función de controlador de errores como el tercer argumento de app.get () me permite detectar el error y devolver el json apropiado:
...
})(req, res, next);
},
function(err, req, res, next) {
// failure in login test route
return res.send({''status'':''err'',''message'':err.message});
});
Yo tuve el mismo problema. Entonces poniendo
const bodyParser=require(''body-parser'');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
bodyparser.json()
estaba causando mi problema, lo solucioné configurándolo por ruta (específicamente en la ruta del pasaporte) de esta manera:
app.post(''/login'', bodyParser.urlencoded({ extended: true }), function (req, res, next) {
passport.authenticate(''local'', function (err, user, info) {
if (err) { return next(err) }
if (!user) {
console.log(''bad'');
req.session.messages = [info.message];
return res.redirect(''/login'')
}
req.logIn(user, function (err) {
console.log(''good'');
if (err) { return next(err); }
return res.redirect(''/'');
});
})(req, res, next);
});