除了verifyCallback之外,我的passport本地策略中的所有内容似乎都在工作,其中validatesPassword
函数的真实性评估无论如何都返回true。这个问题可能源于这样一个事实,即validatesPassword
是一个异步函数,当函数工作不正常时,Promise {<pending>}
的输出不是错误的:
来自密码Utils文件:
async function validatesPassword(passwordInput, dbHash) {
let comparedInput = await bcrypt.compare(passwordInput, dbHash)
//console.log("this is whats returned from compared Input " + comparedInput)
return comparedInput;
}
validatesPassword
中的console.log调用通常在之后打印我的passport文件中passport verifyCallback((函数中的条件语句被调用:
User.findOne(email)
.then((dbResponse) => {
//console.log(dbResponse[0][0]);
let user = dbResponse[0][0];
if (!user) { return done(null, false); }
//no error, but also no user
const isValid = validatesPassword(password, user.hash);
//const isValid = false;
if (isValid) {
return done(null, user);
} else {
return done(null, false);
}
})
.catch((err) => {
console.log(err);
done(err);
});
}
const strategy = new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, verifyCallback);
passport.use(strategy)
...
如上所述,我可以从上述条件中导出false的唯一方法是将isValid
显式设置为false。获得条件等待密码比较(validatesPassword
(函数并评估其返回的布尔函数的最佳方法是什么?我是否应该承诺validatesPassword
并在该函数的内部添加条件(我已经尝试过自己实现,但没有成功(,并将所有这些传递给我的护照文件中的verifyCallback
函数?
validatesPassword()
是一个async
函数。因此,它总是回报一个承诺。
所以,当你这样做的时候:
const isValid = validatesPassword(password, user.hash);
if (isValid) {
// ...
}
这将永远是真实的,因为isValid
是一个承诺,所以if (isValid)
总是会通过。相反,你必须用.then()
或await
来获得承诺的价值,例如:
const isValid = await validatesPassword(password, user.hash);
if (isValid) {
// ...
}
要在那里使用await
,您必须使父函数async
。
使用.then()
并结合到您在问题中显示的代码中,它可以看起来像这样:
User.findOne(email).then((dbResponse) => {
let user = dbResponse[0][0];
if (!user) {
return done(null, false);
}
return validatesPassword(password, user.hash).then(isValid => {
done(null, isValid ? user : false);
});
}).catch((err) => {
console.log(err);
done(err);
});
关于async
和await
的使用,请记住以下几点:
async
函数总是返回一个promise- 当
async
函数命中第一个await
并且该async
函数的执行在该点暂停时,它返回该promise,但是它立即返回promise,并且继续执行接收该promise的调用代码 - 稍后,当使用
await
的内部promise解析时,先前在await
处挂起的函数将继续执行 - 当您最终在该函数(如
return comparedInput;
(中获得返回值时,该返回值将是以前从async
函数返回的promise的解析值。所以,虽然这看起来像是一个同步返回值,但事实并非如此。因为函数是async
,所以返回值将成为它返回的promise的解析值 - 然后,调用者必须使用
await
或.then()
从promise中获取解析的值
jfriend00的回应让我头疼不已,尽管一开始我不确定自己是否理解。我查找了promise中的条件句和依赖于promise的条件句,并提出了这个解决方案,其中我.then((对validatesPassword
进行了处理,然后在其中添加了一个条件:
...
User.findOne(email)
.then((dbResponse) => {
//console.log(dbResponse[0][0]);
let user = dbResponse[0][0];
if (!user) { return done(null, false); }
//no error, but also no user
console.log(
`
here's the dbResponse Object:
user: ${user.username},
password: ${user.hash},
`
);
validatesPassword(password, user.hash)
.then((isValid) => {
if (isValid) {
return done(null, user);
} else {
return done(null, false);
}
})
//const isValid = false;
})
.catch((err) => {
console.log(err);
done(err);
});
}
...
我不确定这是否是jfriend00的建议,但这个解决方案似乎有效。