【发布时间】:2021-02-10 05:30:50
【问题描述】:
我编写了一个方法来更新我的应用程序中的用户,并且在那里一切正常。另外,我写了一些代码,在文档保存之前触发,它不能正常工作。
代码的重点是确定用户是否修改了密码。如果他们没有,只需调用 next()。如果他们这样做了,bcrypt 将对密码进行哈希处理。
这是我正在更新的控制器中的代码:
// @desc Update user by ID
// @route PUT /api/users/:id
// @access Private
const updateUserById = asyncHandler(async (req, res) => {
// Destructure body content from request
const {
firstName,
lastName,
username,
email,
role,
manager,
learningStyle,
departments,
facility,
company,
isActive,
} = req.body;
// Search the database for the user
const user = await User.findById(req.params.id);
// Check to ensure the user was found. Else, respond with 404 error
if (user) {
// Update information accordingly
user.firstName = firstName || user.firstName;
user.lastName = lastName || user.lastName;
user.username = username || user.username;
user.email = email || user.email;
user.role = role || user.role;
user.manager = manager || user.manager;
user.learningStyle = learningStyle || user.learningStyle;
user.departments = departments || user.departments;
user.facility = facility || user.facility;
user.company = company || user.company;
user.isActive = isActive === undefined ? user.isActive : isActive;
// Save user to the database with updated information
const updatedUser = await user.save();
// Send the updated user to the client
res.json(updatedUser);
} else {
res.status(404);
throw new Error("User not found");
}
});
这是我的用户模型代码:
import mongoose from "mongoose";
import bcrypt from "bcryptjs";
const userSchema = mongoose.Schema(
{
firstName: {
// The user's first name
required: true,
type: String,
trim: true,
},
lastName: {
// The user's last name
required: true,
type: String,
trim: true,
},
username: {
// The user's username - user can create their own
required: true,
type: String,
unique: true,
lowercase: true,
},
email: {
// The user's email
required: false,
trim: true,
lowercase: true,
unique: true,
type: String,
},
password: {
// The user's encrypted password (bcrypt hash)
required: true,
type: String,
},
role: {
// The user's role - drives what they're able to do within the application
required: true,
type: mongoose.Schema.Types.ObjectId,
ref: "Role",
},
manager: {
// The user's manager
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: "User",
},
learningStyle: {
// The user's learning style (after assessment is taken)
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: "LearningStyle",
},
departments: [
// The departments the user belongs to (used to drive what the user sees)
// Example: Finishing, Shipping, Printing
{
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: "Department",
},
],
facility: {
// The facility the user works at. Example: Austin Facility
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: "Facility",
},
company: {
// The company the user works for. Example: Microsoft
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Company",
},
isActive: {
required: true,
type: Boolean,
default: true,
},
},
{ timestamps: true }
);
// Match user's password using bcrypt
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
// Generate user's encrypted password on save
userSchema.pre("save", async function (next) {
// Check to see if password is modified. If it is, encrypt it. If not, execute next();
if (!this.isModified("password")) {
console.log("Does this run?");
next();
}
console.log("Does this run as well?");
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
});
const User = mongoose.model("User", userSchema);
export default User;
我有:
- 添加了两个控制台日志,均在模型中触发(参见 userSchema.pre("save"))。
- 试图通过检查密码是否被修改来防止加密触发
- 尝试删除整个用户集合并重新开始
- 课程中的另一个应用程序使用完全相同的方法运行良好
请注意,我的控制器中根本没有更新密码。然而,每次我使用 Postman 发送 PUT 请求并修改名称时,密码都会再次被散列并且两个控制台日志都会触发。
【问题讨论】:
标签: javascript node.js mongodb mongoose