我大约在this tutorial上关注如何使用Passport.js和Postgres对用户进行身份验证。与本文稍有不同的是,我正在使用Sequelize来查询数据库。
以下是相关代码:
-
用于登录和帐户的路由,一旦用户通过身份验证,到/ login的任何GET都应重定向到/ account
登录表单提交的 -
POST路由
-
局部策略
-
序列化/反序列化操作
发生的事情是,当我通过登录表单提交正确的用户名和密码时,控制台输出显示:
loginAttempt: password match succeeded for abcdefg abcdefg
这意味着应该发生的下一件事是成功重定向到/account
并呈现包含用户数据的页面,但是我却被重定向回了/login
,并且得到了故障控制台的输出:
/account: user is not authenticated
这表示尽管在有效的用户名/密码验证之后仍发生了successRedirect,但req.isAuthenticated()
调用仍返回false
。
此处的代码:
app.get('/account',function (req,res,next) {
if(req.isAuthenticated()){
console.log("/account: user is authenticated");
res.render('account',{title: "account",userData: req.user,messages: {danger: req.flash('danger'),warning: req.flash('warning'),success: req.flash('success')}});
}
else{
res.redirect('/login');
}
});
app.get('/login',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",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',{
successRedirect: '/account',failureflash: true
}),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,user);
});
在其他一些Passport.js示例中,我看到成功的密码验证之后是:
return done(null,user);
但是该格式未在本教程中使用,并且我不确定在这种情况下如何从user
对象中获取对象。
那么isAuthenticated()
为什么在成功验证密码后在这里返回false?