虚拟字段未在猫鼬模型中设置字段 [英] Virtual field not setting field in mongoose model
问题描述
我是nodeJS和mongoose的新手.我正在尝试创建一个不会将密码另存为纯文本的用户模型.在其他后端框架中,您可以通过利用虚拟字段使用ORM来完成此任务.我查看了有关Mongoose的文档,发现可以实现.遵循dic,我创建了以下Mongoose模型.请注意,这不是最终的实现,仅用于测试我对Mongoose如何处理虚拟字段的理解.
I am new to nodeJS and mongoose. I am trying to make a user model that does not save a password as plain text. In other backend frameworks you can accomplish this with an ORM by utilizing a virtual field. I looked up the docs for Mongoose and found that this can be accomplished. Following the dics I created the following Mongoose model. Mind you this is not the final implementation and is for merely testing my understanding of how Mongoose handle virtual fields.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {type: String, required: true},
email: {type: String, required: true},
passwordHash: {type: String, required: true}
});
userSchema.virtual("password")
.get(() => this._password)
.set(val => {
this._password = val;
console.log("setting: ", val);
this.passwordHash = "test";
})
module.exports = mongoose.model("Users", userSchema);
我对此模型也进行了以下测试
I also have the following test for this model
it("should not save passwords as plain test", done => {
const user = new User({name: "john", email: "john@example.com", password: "password1234"});
console.log(user);
user.validate(({errors}) => {
expect(errors).to.not.exist
});
done();
});
测试失败,因为我有一个错误.该错误表明passwordHash字段丢失.我知道我根据需要具有该字段,但是我将set函数中的this.passwordHash值指定为"test",就像文档中所说的那样.这就是我卡住的地方.任何指导都非常感激.
The test fails because I have an error. The error states that the passwordHash field is missing. I know I have that field as required, but I assign the value "test" to this.passwordHash in the set function just like the docs say to do. This is where I get stuck. Any guidance is much appreciated.
推荐答案
我认为问题出在userSchema.virtual("password")
函数中的this
上下文
I think problem is with this
context in userSchema.virtual("password")
function
userSchema.virtual("password")
.get(() => this._password) // this points to global object
.set(val => {
this._password = val; // this points to global object
console.log("setting: ", val);
this.passwordHash = "test";
});
当您不能使用箭头功能时,这是例外之一.
This is one of exceptions when you cant use Arrow function.
userSchema.virtual("password")
.get(function() {
return this._password;
})
.set(function(val) {
this._password = val;
console.log("setting: ", val);
this.passwordHash = "test";
});
让我知道它现在可以正常工作了.
Let me know is it working now properly.
我的一般建议:对于散列/检查密码,请使用Schema.pre('save')挂钩.例如:
My general advice: for hash/check passwords use Schema.pre('save') hook. Eg.:
// before save user
userSchema.pre('save', function(next) {
if (this.isModified('password')) { //only if password is modified then hash
return bcrypt.hash(this.password, 8, (err, hash) => {
if (err) {
return next(err);
}
this.password = hash; //save hash in UserSchema.password in database
next();
});
}
next();
});
Schema.pre是中间件的一部分.有关猫鼬中间件的更多信息: http://mongoosejs.com/docs/middleware.html
Schema.pre is part of middleware. More about middleware in mongoose: http://mongoosejs.com/docs/middleware.html
这篇关于虚拟字段未在猫鼬模型中设置字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!