我的護照本地策略中的所有內容似乎都在起作用,除了 verifyCallback,其中validatesPassword
函式的真實性評估無論如何都回傳 true。問題可能源于這樣validatesPassword
一個事實:它是一個異步函式,Promise {<pending>}
并且該函式無序運行時的輸出不是錯誤的:
來自passwordUtils檔案:
async function validatesPassword(passwordInput, dbHash) {
let comparedInput = await bcrypt.compare(passwordInput, dbHash)
//console.log("this is whats returned from compared Input " comparedInput)
return comparedInput;
}
在呼叫我的護照檔案中的護照 verifyCallback() 函式中的條件陳述句之后,validatesPassword
通常會列印console.log 呼叫:
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
我護照檔案中的函式?
uj5u.com熱心網友回復:
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
and的一些注意事項await
:
- 一個
async
函式總是回傳一個promise。 - 它在
async
函式遇到第一個函式時回傳該承諾并且該函式await
的執行async
在該點掛起,但它立即回傳該承諾并繼續執行接收該承諾的呼叫代碼。 - 稍后,當您使用的內部承諾
await
解決時,之前掛起的函式await
將恢復執行。 - 當您最終獲得該函式中的回傳值(例如您的 )時
return comparedInput;
,該回傳值將是先前從該async
函式回傳的承諾的已決議值。所以,雖然這看起來像一個同步回傳值,但它不是。因為函式是async
,回傳值成為它回傳的承諾的決議值。 - 然后呼叫者必須使用
await
或.then()
從承諾中獲取決議的值。
uj5u.com熱心網友回復:
jfriend00 的回答讓我腦子里轉了一圈,雖然我一開始并不確定我是否理解。我查找了在 promises 中使用條件和依賴于 promise 的條件,并提出了這個解決方案,我 .then()'dvalidatesPassword
然后在其中添加了一個條件:
...
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 的建議,但這個解決方案似乎有效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/364906.html
標籤:节点.js 表达 异步等待 护照.js 异步javascript