问题描述
我正在尝试在 MERN 应用程序中实现密码重置功能。每当用户输入他们的电子邮件(他们想要重置密码)并点击“发送密码重置链接”按钮时,就会向路由“/account/forgot”发出 POST 请求。
在路由处理函数中,我检查是否存在任何具有给定电子邮件的用户。如果用户存在,那么我将 resetPasswordLink 和 resetPasswordExpires 属性添加到用户对象,并向客户端发送一条消息“您已通过电子邮件发送密码链接”。
但是,每当我检查数据库时,我都看不到将 resetPasswordLink 和 resetPassworExpires 属性添加到用户中。
问题出在哪里?
代码片段如下:
server/routes/passwordResetRoutes.js
const express = require("express");
const crypto = require("crypto");
const asyncHandler = require("express-async-handler");
const User = require("../models/usermodel");
const router = express.Router();
router.post(
"/forgot",asyncHandler(async (req,res,next) => {
const user = await User.findOne({ email: req.body.email });
if (user) {
user.passwordResetToken = crypto.randomBytes(20).toString("hex");
user.passwordResetExpires = Date.Now() + 3600000;
await user.save();
res.json({
message: "You have been emailed a password reset link",});
} else {
const err = new Error("No account with that email exists");
err.status = 404;
next(err);
}
})
);
module.exports = router;
服务器/模型/usermodel.js
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const userSchema = new mongoose.Schema({
firstName: {
type: String,required: true,},lastName: {
type: String,email: {
type: String,unique: true,password: {
type: String,resetPasswordToken: {
type: String,resetPasswordExpires: {
type: Date,});
userSchema.methods.matchPassword = async function (incomingPassword) {
return await bcrypt.compare(incomingPassword,this.password);
};
userSchema.pre("save",async function (next) {
if (!this.isModified("password")) {
next();
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password,salt);
});
const User = mongoose.model("User",userSchema);
module.exports = User;
解决方法
您正在尝试更新 passwordResetToken
和 passwordResetExpires
字段,但它们不在 User
模型中。这就是 user.save()
调用不执行任何操作的原因。它们应该分别是 resetPasswordToken
和 resetPasswordExpires
。
user.resetPasswordToken = crypto.randomBytes(20).toString('hex')
user.resetPasswordExpires = Date.now() + 3600000
await user.save()