Nodejs Passport аутентифицирует обратный вызов, который не вызывается
Используя Nodejs Passport, я тестировал, что происходит, когда возникает условие ошибки, используя следующий код:
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);
});
Использование маршрута /logintest? username = bob & password = s Я ожидал увидеть в консоли "до аутентификации", затем "в функции auth", затем "аутентифицировать обратный вызов", но он показывает только первые два, за которыми следует "errortest" и "errortest" отображается в браузере.
Я также пробовал return done({'message':'test'});
и "[Object Object]" отображался в консоли и в браузере.
Не работает ли это неправильно или я что-то не хватает?
EDIT: в соответствии с ответом Джареда Хэнсона добавление этой функции обработчика ошибок в качестве третьего аргумента в app.get() позволяет мне уловить ошибку и вернуть соответствующий json:
...
})(req, res, next);
},
function(err, req, res, next) {
// failure in login test route
return res.send({'status':'err','message':err.message});
});
Ответы
Ответ 1
Вы понимаете это отлично и работаете по назначению.
Если возникла какая-либо ошибка, Passport немедленно next()
с этой ошибкой. Вы можете использовать промежуточное программное обеспечение обработки ошибок (подробности: http://expressjs.com/guide/error-handling.html), если вы хотите обработать эту ошибку обычным способом.
Пользовательские обратные вызовы в основном используются для решения проблемы успешности или отказа аутентификации (user
== false
). Ошибки, такие как подключение к БД и т.д., Не возвращаются обратно к обратному вызову в пользу промежуточного программного обеспечения обработки ошибок, описанного выше. Я подумал об этом, но не нашел веских оснований. Но, если у вас есть прецедент, который не описан выше, дайте мне знать.
Ответ 2
bodyparser.json()
вызывал мою проблему, я исправил ее, установив ее по маршруту (в частности, на паспортный маршрут) следующим образом:
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);
});