如何在 Sequelize.then 中执行 bcrypt.compare?
How to execute bcrypt.compare inside Sequelize .then?
我正在尝试构建一个登录页面,在该页面中我使用 Sequelize 从 mysql db 获取散列密码,然后调用 bcrypt compare 对密码进行去散列处理,并将其与用户的登录输入进行比较以进行身份验证。
但是,bcrypt compare 的执行速度总是比 return 慢,导致值始终为“”。我知道这与异步行为有关,但我不知道如何正确编写此代码以使其工作。
authenticate: (req, res) => {
let userDetails = req.query;
User.findOne({
where: {
username: userDetails.username
}
})
.then((user) => {
// How can I make this so, correctPassword() finishes
// and then the authenticated variable will be either false or true?
let authenticated = correctPassword(userDetails.password, user.password);
return authenticated;
})
.then((authenticated) => {
// right now authenticated is "" in client side console.
res.send(authenticated);
})
.catch((error) => {
console.log('there was an error: ', error);
});
}
}
const correctPassword = (enteredPassword, originalPassword) => {
return bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
return res;
});
}
你快到了。你正确地直觉到 correctPassword
是异步执行的,尽管它写得好像它是同步的。
首先,让我们做出 correctPassword
承诺,这样我们就可以使用 async/await
或调用 .then
const correctPassword = (enteredPassword, originalPassword) => {
return new Promise(resolve => {
bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
resolve(res)
});
})
}
接下来,您有两种方法可以确保代码中的操作顺序正确执行:
(推荐)使用 async/await
语法允许我们编写看起来同步的代码:
authenticate: async (req, res) => {
let userDetails = req.query;
try {
const user = await User.findOne({
where: {
username: userDetails.username
}
});
const authenticated = await correctPassword(userDetails.password, user.password);
res.send(authenticated);
} catch(e) {
res.status(400).send(e)
}
}
继续使用承诺:
authenticate: (req, res) => {
let userDetails = req.query;
User.findOne({
where: {
username: userDetails.username
}
}).then(() => {
correctPassword(userDetails.password, user.password)
.then(authenticated => {
res.send(authenticated)
})
.catch(e => {
res.send(e)
})
})
}
您不能将异步函数分配给稍后由同步代码使用的变量。如果你想做同步功能,你可以使用await/aync
。但在这里我建议你也使用 promise 作为比较函数。
User.findOne({
where: {
username: userDetails.username
}
})
.then((user) => {
return correctPassword(userDetails.password, user.password);
})
.then((authenticated) => {
res.send(authenticated);
})
Bcrypt 也支持 promise。
const correctPassword = (enteredPassword, originalPassword) => {
return bcrypt.compare(enteredPassword, originalPassword).then((res) =>{
return res;
});
}
我正在尝试构建一个登录页面,在该页面中我使用 Sequelize 从 mysql db 获取散列密码,然后调用 bcrypt compare 对密码进行去散列处理,并将其与用户的登录输入进行比较以进行身份验证。
但是,bcrypt compare 的执行速度总是比 return 慢,导致值始终为“”。我知道这与异步行为有关,但我不知道如何正确编写此代码以使其工作。
authenticate: (req, res) => {
let userDetails = req.query;
User.findOne({
where: {
username: userDetails.username
}
})
.then((user) => {
// How can I make this so, correctPassword() finishes
// and then the authenticated variable will be either false or true?
let authenticated = correctPassword(userDetails.password, user.password);
return authenticated;
})
.then((authenticated) => {
// right now authenticated is "" in client side console.
res.send(authenticated);
})
.catch((error) => {
console.log('there was an error: ', error);
});
}
}
const correctPassword = (enteredPassword, originalPassword) => {
return bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
return res;
});
}
你快到了。你正确地直觉到 correctPassword
是异步执行的,尽管它写得好像它是同步的。
首先,让我们做出 correctPassword
承诺,这样我们就可以使用 async/await
或调用 .then
const correctPassword = (enteredPassword, originalPassword) => {
return new Promise(resolve => {
bcrypt.compare(enteredPassword, originalPassword, (err, res) =>{
resolve(res)
});
})
}
接下来,您有两种方法可以确保代码中的操作顺序正确执行:
(推荐)使用 async/await
语法允许我们编写看起来同步的代码:
authenticate: async (req, res) => {
let userDetails = req.query;
try {
const user = await User.findOne({
where: {
username: userDetails.username
}
});
const authenticated = await correctPassword(userDetails.password, user.password);
res.send(authenticated);
} catch(e) {
res.status(400).send(e)
}
}
继续使用承诺:
authenticate: (req, res) => {
let userDetails = req.query;
User.findOne({
where: {
username: userDetails.username
}
}).then(() => {
correctPassword(userDetails.password, user.password)
.then(authenticated => {
res.send(authenticated)
})
.catch(e => {
res.send(e)
})
})
}
您不能将异步函数分配给稍后由同步代码使用的变量。如果你想做同步功能,你可以使用await/aync
。但在这里我建议你也使用 promise 作为比较函数。
User.findOne({
where: {
username: userDetails.username
}
})
.then((user) => {
return correctPassword(userDetails.password, user.password);
})
.then((authenticated) => {
res.send(authenticated);
})
Bcrypt 也支持 promise。
const correctPassword = (enteredPassword, originalPassword) => {
return bcrypt.compare(enteredPassword, originalPassword).then((res) =>{
return res;
});
}