mongoose钩访问原始参数

我想哈希我的用户密码创build一个帐号mongoose,设置一个钩子asynchronous散列的密码,并设置帐户_password属性。

var accountSchema = new mongoose.Schema({ name: {type : String}, _password : {type : String} }) accountSchema.pre('save', true, function hook (next, done) { next(); doHashPassword(done); }); var Account = mongoose.model('Account', accountSchema); Joe = new Account({name : "Joe", password : "secret"}); Joe.save(); 

我如何在我的散列函数/钩子中访问Joe({名称:“Joe”,密码:“secret”})的原始参数? 由于密码未映射到私有属性(这是为了不意外地以明文forms设置密码)

提前致谢

我不是100%确定你可以访问不属于模式的原始属性。

我知道有一个选项可以启用/禁用在数据库中保存非模式属性,所以请谨慎发送{name:'Joe',密码:'secret'}这样的选项被禁用,或者你会不小心创build并设置“密码”。 自从我研究过这个版本之后,它已经有几个版本了,所以你可能会好起来的。

通常,我们不是使用常规的“设置”密码,而是创build一个实例方法,如下所示:

 var joe = new Account({ name: 'Joe' }); joe.setPassword('secret', function() { joe.save(); }); 

这具有封装密码逻辑的良好副作用(而不是依赖于不太明显的钩子)并且使得密码pipe理成为明确的活动。 像这样的东西可能适合你:

 accountSchema.methods.setPassword = function(plain, done) { var self = this; doHashPassword(plain, function(err, result) { self._password = result; if (done) done(); }); }; 

mongoose文档有创build实例方法的指南:

你也可以在这个一般情况下添加一些糖,并使其可链接,或忽略setPassword()的callback,或将setPassword()更改为savePassword(),以便在完成后不必担心保存。等等很多的select。

你可能不想永远以纯文本的forms存储密码,对吗? 你可以做的是在模式上创build一个虚拟属性,它将立即散列密码并将其添加到模型中。

这是未经testing的,但我会做这样的事情:

 var accountSchema = new mongoose.Schema({ name: {type : String}, _password : {type : String} }) accountSchema.virtual('password') // Setting the password property will put the hashed string into _password .set(function(s) { this._password = myHashFn(s); }) // If you want to have a getter, implement it here .get(function() { return "********"; }); var Account = mongoose.model('Account', accountSchema); Joe = new Account({name : "Joe", password : "secret"}); Joe.save(); 

我通过另外一个问题find了解决这个问题的方法,诺亚在这个问题上发表了一篇关于这个问题的博文。

http://blog.mongodb.org/post/32866457221/password-authentication-with-mongoose-part-1

他们使用预存储钩子。 我错过了将密码设置为明文密码的那一刻密码没有保存的地步,只存在于内存中。 如果我调用保存密码被asynchronous覆盖并保存哈希成功。

感谢大家的帮助