Passport、Bcryptjs、Async/Await:verify函数将密码中的任何输入传递为true



除了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);
});

关于asyncawait的使用,请记住以下几点:

  1. async函数总是返回一个promise
  2. async函数命中第一个await并且该async函数的执行在该点暂停时,它返回该promise,但是它立即返回promise,并且继续执行接收该promise的调用代码
  3. 稍后,当使用await的内部promise解析时,先前在await处挂起的函数将继续执行
  4. 当您最终在该函数(如return comparedInput;(中获得返回值时,该返回值将是以前从async函数返回的promise的解析值。所以,虽然这看起来像是一个同步返回值,但事实并非如此。因为函数是async,所以返回值将成为它返回的promise的解析值
  5. 然后,调用者必须使用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的建议,但这个解决方案似乎有效。

相关内容

最新更新