如何让我的 User.findByIdAndUpdate 仅在密码设置为我的新密码后运行?
How can I make my User.findByIdAndUpdate runs only after the password is set to my new password?
所以这是我的代码,基本上我想做的是在用户想要更改密码时更改密码,否则,它将保持不变。虽然,当我更改它时,它不会被散列,因为它会自动接受来自前端的输入 (req.body.password)。看起来最后一个 promise 并没有等待前一个完成并获取设置为新密码的密码。
profileRoutes.put("/profile/:userid", (req, res) => {
const { userid } = req.params;
const { firstName, lastName, email, imageUrl } = req.body;
let password = req.body.password;
let newPassword = null;
// We need a validation here?
User.findById(userid)
.then((user) => {
console.log("user", user);
console.log(user.password === password);
if (user.password !== password) {
console.log("setting the new pass");
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
console.log("password:", password, "newPassword:", newPassword);
password = newPassword;
}
}).then(User.findByIdAndUpdate(
userid,
{ firstName, lastName, email, imageUrl, password },
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
})
);
});
这是我在控制台中得到的:
user {
[0] imageUrl: 'http://media.istockphoto.com/vectors/default-profile-picture-avatar-photo-placeholder-vector-illustration-vector-id1223671392?k=6&m=1223671392&s=612x612&w=0&h=NGxdexflb9EyQchqjQP0m6wYucJBYLfu46KCLNMHZYM=',
[0] role: 'USER',
[0] fileUrl: [],
[0] _id: 60d70093e08f660bebec5589,
[0] firstName: 'Tiago',
[0] lastName: 'Pereira',
[0] email: 'tiago@gmail.com',
[0] password: 'a$yExMB9eSs1EyqSbrvE8a1udqOMo09GG.SSyr0BJmZb70mqpcJByiC',
[0] createdAt: 2021-06-26T10:25:23.245Z,
[0] updatedAt: 2021-06-26T10:25:23.245Z,
[0] __v: 0
[0] }
[0] false
[0] setting the new pass
[0] password: qwertyasd newPassword: a$Xudvsq4CkkDU7bHcQIvH.OyfhlDe1/u3Q1Qv6wmv79f4B5TSFVDi.
[0] response after update {
[0] imageUrl: 'https://res.cloudinary.com/dulzxixhi/image/upload/v1624703139/School%27s%20Cool/wnc8vjpgunrkvolnldb4.jpg',
[0] role: 'USER',
[0] fileUrl: [],
[0] _id: 60d70093e08f660bebec5589,
[0] firstName: 'Tiago',
[0] lastName: 'Pereira',
[0] email: 'tiago@gmail.com',
[0] password: 'qwertyasd',
[0] createdAt: 2021-06-26T10:25:23.245Z,
[0] updatedAt: 2021-06-26T10:26:20.237Z,
[0] __v: 0
[0] }
首先,您不能直接将散列密码与普通字符串进行比较。
console.log(user.password === password); //this will always prints false
你必须使用 bcrypt.compareSync
。它需要两个输入(普通字符串、散列)和 return 一个布尔值(如果匹配则为真)。
并且您在 Bcrypt 中使用同步方法,因此它不会 return 一个承诺。这意味着您不能使用 .then()
.
对现有代码改动最少的解决方案:
只需在 if 块中使用 findByIdAndUpdate
。
const isMatching = bcrypt.compareSync(password, user.password);
if (isMatching) {
console.log("setting the new pass");
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
console.log("password:", password, "newPassword:", newPassword);
password = newPassword;
User.findByIdAndUpdate(
userid,
{ firstName, lastName, email, imageUrl, password },
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
})
}
解决方法其实很简单。我们要return我们要通过的东西:
User.findById(userid)
.then((user) => {
if (user.password !== password) {
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
password = newPassword;
}
return password;
// I am returning the password to be able to pass it to the next then() and
// use it as follows
})
.then((password) => {
User.findByIdAndUpdate(
userid,
{
firstName,
lastName,
email,
imageUrl,
password,
newChannelEmailNotification,
newEventEmailNotification,
newPostEmailNotification,
},
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
});
});
});
所以这是我的代码,基本上我想做的是在用户想要更改密码时更改密码,否则,它将保持不变。虽然,当我更改它时,它不会被散列,因为它会自动接受来自前端的输入 (req.body.password)。看起来最后一个 promise 并没有等待前一个完成并获取设置为新密码的密码。
profileRoutes.put("/profile/:userid", (req, res) => {
const { userid } = req.params;
const { firstName, lastName, email, imageUrl } = req.body;
let password = req.body.password;
let newPassword = null;
// We need a validation here?
User.findById(userid)
.then((user) => {
console.log("user", user);
console.log(user.password === password);
if (user.password !== password) {
console.log("setting the new pass");
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
console.log("password:", password, "newPassword:", newPassword);
password = newPassword;
}
}).then(User.findByIdAndUpdate(
userid,
{ firstName, lastName, email, imageUrl, password },
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
})
);
});
这是我在控制台中得到的:
user {
[0] imageUrl: 'http://media.istockphoto.com/vectors/default-profile-picture-avatar-photo-placeholder-vector-illustration-vector-id1223671392?k=6&m=1223671392&s=612x612&w=0&h=NGxdexflb9EyQchqjQP0m6wYucJBYLfu46KCLNMHZYM=',
[0] role: 'USER',
[0] fileUrl: [],
[0] _id: 60d70093e08f660bebec5589,
[0] firstName: 'Tiago',
[0] lastName: 'Pereira',
[0] email: 'tiago@gmail.com',
[0] password: 'a$yExMB9eSs1EyqSbrvE8a1udqOMo09GG.SSyr0BJmZb70mqpcJByiC',
[0] createdAt: 2021-06-26T10:25:23.245Z,
[0] updatedAt: 2021-06-26T10:25:23.245Z,
[0] __v: 0
[0] }
[0] false
[0] setting the new pass
[0] password: qwertyasd newPassword: a$Xudvsq4CkkDU7bHcQIvH.OyfhlDe1/u3Q1Qv6wmv79f4B5TSFVDi.
[0] response after update {
[0] imageUrl: 'https://res.cloudinary.com/dulzxixhi/image/upload/v1624703139/School%27s%20Cool/wnc8vjpgunrkvolnldb4.jpg',
[0] role: 'USER',
[0] fileUrl: [],
[0] _id: 60d70093e08f660bebec5589,
[0] firstName: 'Tiago',
[0] lastName: 'Pereira',
[0] email: 'tiago@gmail.com',
[0] password: 'qwertyasd',
[0] createdAt: 2021-06-26T10:25:23.245Z,
[0] updatedAt: 2021-06-26T10:26:20.237Z,
[0] __v: 0
[0] }
首先,您不能直接将散列密码与普通字符串进行比较。
console.log(user.password === password); //this will always prints false
你必须使用 bcrypt.compareSync
。它需要两个输入(普通字符串、散列)和 return 一个布尔值(如果匹配则为真)。
并且您在 Bcrypt 中使用同步方法,因此它不会 return 一个承诺。这意味着您不能使用 .then()
.
对现有代码改动最少的解决方案:
只需在 if 块中使用 findByIdAndUpdate
。
const isMatching = bcrypt.compareSync(password, user.password);
if (isMatching) {
console.log("setting the new pass");
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
console.log("password:", password, "newPassword:", newPassword);
password = newPassword;
User.findByIdAndUpdate(
userid,
{ firstName, lastName, email, imageUrl, password },
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
})
}
解决方法其实很简单。我们要return我们要通过的东西:
User.findById(userid)
.then((user) => {
if (user.password !== password) {
const salt = bcrypt.genSaltSync(10);
newPassword = bcrypt.hashSync(password, salt);
password = newPassword;
}
return password;
// I am returning the password to be able to pass it to the next then() and
// use it as follows
})
.then((password) => {
User.findByIdAndUpdate(
userid,
{
firstName,
lastName,
email,
imageUrl,
password,
newChannelEmailNotification,
newEventEmailNotification,
newPostEmailNotification,
},
{ new: true }
)
.then((response) => {
console.log("response after update", response);
res.status(200).json({ message: `User ${userid} has been updated` });
})
.catch((err) => {
console.log(err);
res
.status(500)
.json({ message: "Something went wrong updating the user" });
});
});
});