Я примерно следую этому руководству о том, как использовать Passport.js и Postgres для аутентификации пользователей. Небольшое изменение статьи заключается в том, что я использую Sequelize для запроса базы данных.
Вот соответствующий код для:
маршрутов для входа в систему и учетной записи, после того какПользователь проходит проверку подлинности. Любой запрос GET на / login должен перенаправлять на / account
POST-маршрут, который форма входа отправляет на
local-стратегии
операции сериализации / десериализации
Происходит следующее: когда я отправляю правильное имя пользователя и пароль через форму входа в систему, вывод консоли показывает:
loginAttempt: password match succeeded for abcdefg abcdefg
Это означает, что следующее, что должно произойти, - это successRedirect на /account
и рендеринг страницы с данными пользователя, но вместо этого я перенаправляюсь обратно на /login
и получаю вывод консоли ошибки:
/account: user is not authenticated
Это указывает на то, что вызов req.isAuthenticated()
возвращает false
, несмотря на то, что successRedirect происходит после подтверждения действительного имени пользователя / пароля.
Код здесь:
app.get('/account', function (req, res, next) {
if(req.isAuthenticated()){
console.log("/account: user is authenticated");
res.render('account', {title: "Account", userData: req.user, userData: req.user, messages: {danger: req.flash('danger'), warning: req.flash('warning'), success: req.flash('success')}});
}
else{
res.redirect('/login');
}
});
app.get('/login', function (req, res, next) {
if (req.isAuthenticated()) {
console.log("/login: user is authenticated");
res.redirect('/account');
}
else{
console.log("/login: user is not authenticated");
res.render('login', {title: "Log in", userData: req.user, messages: {danger: req.flash('danger'), warning: req.flash('warning'), success: req.flash('success')}});
}
});
app.post('/login', passport.authenticate('local', {
successRedirect: '/account',
failureRedirect: '/login',
failureFlash: true
}), function(req, res) {
if(res!=false){
console.log("/login: res: "+res);
}
if (req.body.remember) {
req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // Cookie expires after 30 days
} else {
req.session.cookie.expires = false; // Cookie expires at end of session
}
res.redirect('/');
});
app.post('/login', passport.authenticate('local', {
successRedirect: '/account',
failureRedirect: '/login',
failureFlash: true
}), function(req, res) {
console.log("/login: running done function");
if(res!=false){
console.log("/login: res: "+res);
}
if (req.body.remember) {
req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // Cookie expires after 30 days
} else {
req.session.cookie.expires = false; // Cookie expires at end of session
}
res.redirect('/');
});
passport.use('local', new LocalStrategy({passReqToCallback : true}, (req, username, password, done) => {
loginAttempt();
async function loginAttempt() {
var bcryptResult;
try{
var result;
await sequelize.query('BEGIN')
try{
result = await sequelize.query('SELECT id_uuid, firstName, email, passwordhash FROM users WHERE email=?', {
replacements:[username],
type:sequelize.QueryTypes.SELECT});
}
catch(err){
return done(err);
}
console.log("loginAttempt: select query completed, result: "+JSON.stringify(result[0]));
if (result.length==0){
req.flash('danger', "Oops. Incorrect login details.");
return done(null,false);
}
else{
try{
bcryptResult=await bcrypt.compare(password, result[0].passwordhash);
}
catch(err){
console.log('Error while checking password');
return done();
}
try{
if(bcryptResult){
var email=result[0].email;
var firstName=result[0].firstname;
console.log("loginAttempt: password match succeeded for "+email+" "+firstName);
return done(null,[{
email:email,
firstName:firstName
}]);
}
else{
req.flash('danger',"Oops. Incorrect login details.");
return done(null,false);
}
}
catch(e){
console.log("loginAttempt: error: "+e);
}
}
}
catch(e){
throw (e);
}
};
}
))
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
Понятнов некоторых других примерах Passport.js за успешной проверкой пароля следуют:
return done(null,user);
, но этот формат не используется в руководстве, и я не уверен, где взять мой user
объект из в этом случае.
Так почему isAuthenticated()
возвращает здесь false после успешной проверки пароля?