为了在将对象保存到mongodb之前散列密码,我使用内置的预保存挂钩与mongoose一起使用。 但是在更新期间处理散列的正确方法是什么?
我尝试使用预更新挂钩来解决这个问题,但这有一些明显的缺点,因为它绕过了模型验证(例如密码长度)。
这是我的方法(缩短):
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;
});
});
那么,解决这个问题的首选方法是什么?
答案 0 :(得分:3)
我会使用pre '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();
});
[...]
尽管在使用时将值转换为适当的类型 更新,以下内容不适用:
- 默认
- 制定者
- 验证
- 中间件
如果您需要这些功能,请使用 首先检索文档的传统方法。
可验证的例子:
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();
});
});
示例的额外信息: