使用mongoose在更新时对密码进行哈希处理

7
为了在将对象保存到MongoDB之前对密码进行哈希,我使用了Mongoose自带的pre-save hook。但是在更新期间如何正确地处理哈希呢?
我尝试通过pre-update hook来解决这个问题,但是这有一些显著的缺点,比如它绕过了模型验证(例如密码长度)。
这是我的方法(简化版):
userSchema.pre('findOneAndUpdate', function (next) {
    let query = this;
    let update = query.getUpdate();

    if (!update.password) {
        return next();
    }

    hashPassword(update.password, function (err, hash) {
        //handle error or go on...
        //e.g update.password = hash;
    });
});

那么,解决这个问题的首选方法是什么?
1个回答

9

我会使用预先 'save' 中间件:

AccountSchema.pre('save', function(next) {
  this._doc.password = encrypt(this._doc.password);
  next();
});

但是这需要在更新文档时也使用save

Account.findById(id, function(err, doc) {
    if (err) return false;
    doc.password = "baloony2";
    doc.save();
  });

根据更新文档所述:
[...] 尽管使用update时值会被转换为适当的类型,但以下内容不会被应用:
- 默认值 - setter - 验证器 - 中间件
如果需要这些功能,请使用传统方法首先检索文档。
一个可验证的例子:
const crypto = require('crypto');
const algorithm = 'aes-256-ctr';
const password = 'aSjlkvS89';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

mongoose.connect("mongodb://localhost:33023/test_1");
mongoose.Promise = require('bluebird');

function encrypt(text) {
  var cipher = crypto.createCipher(algorithm, password);
  var crypted = cipher.update(text, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
}

// SCHEMA -------------------------------------------------

var AccountSchema = new Schema({
  name: {
    type: String,
    unique: true
  },
  password: String
});

var id;

AccountSchema.pre('save', function(next) {
  id = this._doc._id;
  var pwd = this._doc.password;
  console.log("hashing password: " + pwd);
  this._doc.password = encrypt(pwd);
  next();
});

// MODEL --------------------------------------------------

var Account = mongoose.model('Account', AccountSchema);

// DATA ---------------------------------------------------

new Account({
  name: "john",
  password: "baloony1"
})
.save()
.then(function(res) {
  Account.findById(id, function(err, doc) {
    if (err) return false;
    doc.password = "baloony2";
    doc.save();
  });
});

关于示例的额外信息:


嗨,我需要你的帮助:https://stackoverflow.com/questions/62066921/hashed-password-update-with-mongoose-express# - Denn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接