虚拟字段未在猫鼬模型中设置字段 [英] Virtual field not setting field in mongoose model

查看:97
本文介绍了虚拟字段未在猫鼬模型中设置字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆