Mongoose创建用户时提示hashed_password is required报错求助
问题排查与修复方案
核心根因
- 你在virtual字段的set/get方法中使用了箭头函数,导致this丢失了指向Mongoose文档实例的绑定,你只能拿到上层作用域的this,因此错误地选择直接操作
userSchema对象赋值。 userSchema是全局的模式定义对象,你把salt、hashed_password等实例独有的属性赋值到userSchema上,根本不会同步到你要保存的用户文档实例中,因此实例的hashed_password始终为空,触发必填校验报错。- 加密方法中读取的
userSchema.salt是模式对象上的属性,不是当前实例的salt,就算赋值成功也会出现多用户创建时属性互相覆盖的并发问题。
修复方案
把所有涉及文档实例操作的箭头函数替换为普通function,所有实例属性通过this赋值即可,修复后的代码如下:
const mongoose = require("mongoose"); const crypto = require("crypto"); const uuidv1 = require("uuid").v1; const userSchema = new mongoose.Schema( { name: { type: String, trim: true, required: true, maxlength: 32, }, email: { type: String, trim: true, required: true, unique: true, // 原代码unique:32为错误写法,unique为布尔类型属性 }, hashed_password: { type: String, required: true, }, about: { type: String, trim: true, }, salt: { type: String, }, role: { type: Number, default: 0, }, history: { type: Array, default: [], }, }, { timestamps: true } ); // Virtual field 替换箭头函数为普通function,恢复this指向文档实例 userSchema .virtual("password") .set(function(password) { this._password = password; this.salt = uuidv1(); this.hashed_password = this.encryptPassword(password); }) .get(function() { return this._password; }); // Encrypt the Password userSchema.methods = { encryptPassword: function (password) { if (!password) { return ""; } try { return crypto .createHmac("sha1", this.salt) // 读取当前实例的salt .update(password) .digest("hex"); } catch (e) { console.log(typeof password, password); console.log(typeof this.salt, this.salt); return ""; } }, };
内容的提问来源于stack exchange,提问作者IndexError
相关产品推荐
相关产品推荐

