Node.js 猫鼬模式';t调用中间件来散列密码

Node.js 猫鼬模式';t调用中间件来散列密码,node.js,mongoose,password-encryption,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,

我的猫鼬模式如下所示:

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;
};
我使用此模式更新收藏中的记录,如下所示:

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()
保持未调用状态。如何修复此问题?

在您的
createAccount
函数中,您使用了该函数,该函数只是触发
findOneAndUpdate
中间件,而不是
save
中间件,因此无法访问
控制台.log

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

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

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