猫鼬模式不会调用中间件来哈希密码

时间:2019-08-20 20:29:03

标签: node.js mongoose password-encryption

我的猫鼬模式如下:

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;

我正在使用这种模式来更新集合中的记录,如下所示:

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()未被调用。我该如何解决?

1 个答案:

答案 0 :(得分:1)

createAccount函数中,您使用了findOneAndUpdate(),此函数仅触发findOneAndUpdate中间件,而不触发save中间件,因此未达到console.log

您可以通过以下方式解决问题:

  • 选项1:使用findOne()findById()查找用户,更改其字段,然后调用save()。它将触发您的save中间件。

  • 选项2:注册findOneAndUpdate中间件并在其中哈希密码,但请注意,findOneAndUpdate查询中间件,因此thís将引用查询,而不是save中间件中的文档。