猫鼬模式不会调用中间件来散列密码

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 中间件中的文档。