Как я могу правильно сообщить о недопустимом входе в систему с помощью Express и PassportJS?
-
13-12-2019 - |
Вопрос
Я успешно внедрил pass-local в свое веб-приложение Express/Mongoose, но мне не удается понять, как правильно отобразить сообщение о неудачном входе в систему.
Вот мой путь входа:
app.get('/login', function(req, res) {
res.render('user/login', {
});
});
При таком маршруте как я могу сообщить о недействительном входе в систему?Если вход успешен, он напишет id
/username
к req.user
объект, но это не помогает мне в "GET /login"
маршрут, потому что в случае успеха вы будете перенаправлены на страницу, на которую хотите перейти.
Это значит req.user
всегда будет undefined
когда ты GET
страница входа.
Я хочу быть в состоянии написать сообщение, в котором говорится что -то вроде «йо, неверный логин!» Когда случаются следующие вещи:
- Пользователь не существует.
- Указанный пароль не соответствует, но пользователь существует.
Возможно, я захочу вывести другое сообщение в зависимости от того, что произошло.
Когда я реализовал LocalStrategy, я использовал этот код:
passport.use(new LocalStrategy({
usernameField: 'email'
},
function(email, password, fn) {
User.findOne({'login.email': email}, function(err, user) {
// Error was thrown.
if (err) {
return fn(err);
}
// User does not exist.
if (!user) {
return fn(null, false);
}
// Passwords do not match.
if (user.login.password != utility.encryptString(user.login.salt + password)) {
return fn(null, false);
}
// Everything is good.
return fn(null, user);
});
}
));
Как видите, есть некоторые проблемы, но автор PassportJS настроил свое приложение именно так.Как мы должны получить доступ к тому, что возвращает Стратегия?
Например, если выдает ошибку, что мне вообще нужно позвонить, чтобы получить доступ к err
?
Спасибо.
Решение
Вы можете использовать настраиваемый обратный вызов или функцию промежуточного программного обеспечения, чтобы иметь больше контроля.См. Аутентификация раздел руководства с примерами.
Например, индивидуальный обратный вызов может выглядеть так:
app.get('/login', function(req,res,next) {
passport.authenticate('local', function(err,user) {
if(!user) res.send('Sorry, you\'re not logged in correctly.');
if(user) res.send('Skeet skeet!');
})(req,res,next);
});
Альтернативно, вы всегда можете перенаправить оба ответа:
app.get('/login',
passport.authenticate('local', { successRedirect: '/winner',
failureRedirect:'/loser' }));
Или перенаправьте ошибку с помощью простого промежуточного программного обеспечения:
app.get('/login', ensureAuthenticated,
function(req,res) {
// successful auth
// do something for-the-win
}
);
// reusable middleware
function ensureAuthenticated(req,res,next) {
if(req.isAuthenticated()) {return next();}
res.redirect('/login/again'); // if failed...
}
Другие советы
В последней версии Passport я добавил поддержку флэш-сообщений, которые позволяют легко делать то, что вы просите.
Теперь вы можете указать третий аргумент для done
, который может включать сообщение об ошибке.Например:
if (user.login.password != utility.encryptString(user.login.salt + password)) {
return fn(null, false, { message: 'yo, invalid login!' });
}
Затем установите failureFlash
к true
как вариант authenticate()
.
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true });
В этом случае, если аутентификация не удалась, сообщение будет установлено во флэш-памяти, и вы сможете его отобразить при повторном отображении страницы входа.
Пользовательские обратные вызовы также вполне подходят.Встроенные опции просто упрощают выполнение обычных задач.
Еще мне интересно:Вы упоминаете, что есть проблемы с образцом.Что, по вашему мнению, следует улучшить?Я хочу сделать примеры как можно лучше.Спасибо!
(Подробнее см. здесь комментарий по вопросу №12).