猫鼬模式不会调用中间件来散列密码
Mongoose schema wouldn't call middleware to hash password
我的 Mongoose 架构如下所示:
import mongoose from 'mongoose';
import argon2 from 'argon2';
import argonConfigs from '../configs/argon-configs';
const { Schema } = mongoose;
const userSchema = new Schema({
firstName: String,
lastName: String,
googleID: String,
twitterID: String,
emails: [String],
hasPicture: Boolean,
signupToken: String,
token: String,
username: String,
password: String,
});
userSchema.pre('save', async function(next) {
console.log('inside pre');
if (this.password) {
console.log('this.password', this.password);
this.password = await argon2.hash(password, argonConfigs);
}
next();
});
const User = mongoose.model('user', userSchema);
module.exports = User;
我使用这个模式来更新我 collection 中的记录,如下所示:
import User from '../models/user';
export const tokenInDB = async (token, email) => {
const existingUser = await User.findOne({ token: token, emails: email, password : { $exists : false } });
return existingUser;
};
export const createAccount = async (fname, lname, uname, pass, existingUser) => {
let fieldsToUpdate = {};
if(fname) { fieldsToUpdate.firstName = fname }
if(lname) { fieldsToUpdate.lastName = lname }
if(uname) { fieldsToUpdate.username = uname }
if(pass) { fieldsToUpdate.password = pass }
const updatedUser = await User.findOneAndUpdate({_id: existingUser._id}, {...fieldsToUpdate, $unset: {token: 1}}, {new: true});
return updatedUser;
};
我希望中间件 (userSchema.pre()
) 在每次更新时都能启动。然后这个中间件应该使用 argon2i
库来散列用户输入的明文密码。
但是,中间件拒绝被调用。函数内的 console.log()
保持未调用状态。我该如何解决这个问题?
在您的 createAccount
函数中,您使用了 findOneAndUpdate() 并且此函数仅触发 findOneAndUpdate
中间件,而不是 save
中间件,因此未到达 console.log
。
您可以通过以下方式解决您的问题:
选项 1:使用 findOne()
或 findById()
查找用户,更改其字段,然后调用 save()
。它会触发你的 save
中间件。
选项 2:注册 findOneAndUpdate
中间件并在其中散列您的密码,但请注意,findOneAndUpdate
是 查询中间件 所以thís
将引用查询,而不是 save
中间件中的文档。
我的 Mongoose 架构如下所示:
import mongoose from 'mongoose';
import argon2 from 'argon2';
import argonConfigs from '../configs/argon-configs';
const { Schema } = mongoose;
const userSchema = new Schema({
firstName: String,
lastName: String,
googleID: String,
twitterID: String,
emails: [String],
hasPicture: Boolean,
signupToken: String,
token: String,
username: String,
password: String,
});
userSchema.pre('save', async function(next) {
console.log('inside pre');
if (this.password) {
console.log('this.password', this.password);
this.password = await argon2.hash(password, argonConfigs);
}
next();
});
const User = mongoose.model('user', userSchema);
module.exports = User;
我使用这个模式来更新我 collection 中的记录,如下所示:
import User from '../models/user';
export const tokenInDB = async (token, email) => {
const existingUser = await User.findOne({ token: token, emails: email, password : { $exists : false } });
return existingUser;
};
export const createAccount = async (fname, lname, uname, pass, existingUser) => {
let fieldsToUpdate = {};
if(fname) { fieldsToUpdate.firstName = fname }
if(lname) { fieldsToUpdate.lastName = lname }
if(uname) { fieldsToUpdate.username = uname }
if(pass) { fieldsToUpdate.password = pass }
const updatedUser = await User.findOneAndUpdate({_id: existingUser._id}, {...fieldsToUpdate, $unset: {token: 1}}, {new: true});
return updatedUser;
};
我希望中间件 (userSchema.pre()
) 在每次更新时都能启动。然后这个中间件应该使用 argon2i
库来散列用户输入的明文密码。
但是,中间件拒绝被调用。函数内的 console.log()
保持未调用状态。我该如何解决这个问题?
在您的 createAccount
函数中,您使用了 findOneAndUpdate() 并且此函数仅触发 findOneAndUpdate
中间件,而不是 save
中间件,因此未到达 console.log
。
您可以通过以下方式解决您的问题:
选项 1:使用
findOne()
或findById()
查找用户,更改其字段,然后调用save()
。它会触发你的save
中间件。选项 2:注册
findOneAndUpdate
中间件并在其中散列您的密码,但请注意,findOneAndUpdate
是 查询中间件 所以thís
将引用查询,而不是save
中间件中的文档。