"这"没有在mongoose模型

时间:2017-07-07 06:10:33

标签: javascript node.js express mongoose

我有以下代码将用户对象从express保存到数据库,

api.post('/signup', function (req, res) {
    var user = new User();
    user.name = req.body.name;
    user.email = req.body.email;
    user.setPassword(req.body.password);
    user.save(function (err) {
        err ? res.send(err) : res.json({ message: 'User Created!'})
    })
})

以及此处的用户架构

var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var SALT_WORK_FACTOR = 10;

var Schema = mongoose.Schema;

var userSchema = new Schema({
    name: { 
        type: String,
        required: true
    },
    email: {
        type: String,
        unique: true,
        required: true
    },
    password: String,
})

userSchema.methods.setPassword = function (password) {
    bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
        if (err) return console.log(err);
        bcrypt.hash(password, salt, function (err, hash) {
            if (err) return console.log(err);
            this.password = hash; // <= `this` will not be saved to mongoDB
        })
    })
}

module.exports = mongoose.model('User', userSchema);

执行save功能时,它会显示passwordundefined并将对象保存到没有password值的mongodb。

我也检查了this question,并将我的所有功能更改为不使用箭头方法,但仍然出现相同的错误。

当我使用中间件挂钩this引用不是指用户对象时,同样的问题。下面是我的另一种方法,

userSchema.pre('save', (next) => {

    bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
        if(err) return next(err);
        bcrypt.hash(this.password, salt, function (err, hash) {
            if (err) return next(err);

            this.password = hash; // <= `this` will not be saved to mongoDB
            next();
        })
    })
})

在执行save时,是否要将此值保存到数据库?

3 个答案:

答案 0 :(得分:0)

你应该尝试下面的代码,希望它能为你效用:

userSchema.methods.setPassword = function (password) {
    var pswd=password;
    bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
        if (err) return console.log(err);
        bcrypt.hash(pswd, salt, function (err, hash) {
            if (err) return console.log(err);
            pswd = hash;
            console.log(pwsd); // your decripted password
        })
    })
}

答案 1 :(得分:0)

我将在接下来的日子里详细说明(我想测试一些事情),但我认为错误是因为JS中Clear()的含义很棘手。

基本上this不是对函数的词法范围的引用,它是在调用函数的上下文中完成的。

因此,作为一个快速的解决方案,我详细说明,我建议你加密密码: this并简化user.setPassword(encrypt(req.body.password));

希望有所帮助。

答案 2 :(得分:0)

如果您希望this引用userSchema上下文,则可以使用箭头函数进行bcrypt回调。箭头函数不会创建新的函数范围,因此它将保留原始上下文。

userSchema.methods.setPassword = function (password) { 
  bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => { 
    if (err) return console.log(err);    
    bcrypt.hash(password, salt, (err, hash) => { 
      if (err) return console.log(err);
      this.password = hash; // <= `this` will be the user object
    })
  })
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions