mongoose“架构方法”callback不起作用

我是新来的mongoose和node.js。 我尝试按照这个教程: https : //scotch.io/tutorials/using-mongoosejs-in-node-js-and-mongodb-applications#sample-model-for-users

在我的入口点index.js中,我试图调用“chenya.saltHashPassword(function(err,passwordHash)”,它实际上是在user.js中调用的,因为user.js可以打印出三条日志消息,但是没有日志这个方法的消息在index.js中调用,而save方法可以打印出表示成功保存的日志消息:

//Lets load the mongoose module in our program var mongoose = require('mongoose'); //Lets connect to our database using the DB server URL. mongoose.connect('mongodb://localhost:27017/server_naturis'); // if our user.js file is at app/models/user.js var User = require('./user'); // create a new user called Chenya var chenya = new User({ userName: 'Chenya', email: 'chenya@gmail.com', password: 'Chenya' }); // call the custom method. hash the password chenya.saltHashPassword(function(err, passwordHash) { // NOT CALLED! if (err) { console.log('chenya.saltHashPassword: ' + err); } else { this.password = passwordHash; console.log('Your hashed password is ' + passwordHash); } }); // call the built-in save method to save to the database chenya.save(function(err) { // CALLED! if (err) { console.log('chenya.save: ' + err); } else { console.log('User saved successfully!'); } }); 

在我的user.js中,我有模式函数“userSchema.methods.saltHashPassword”:

 // grab the things we need var mongoose = require('mongoose'); var Schema = mongoose.Schema; // Require the crypto module for password hash 'use strict'; var crypto = require('crypto'); // create a schema var userSchema = new Schema({ userName: { type: String, required: true, unique: true }, email: { type: String, required: true, unique: true }, password: { type: String, required: true }, }); // add a schema method /** * generates random string of characters ie salt * @function * @param {number} length - Length of the random string. */ var genRandomString = function(length){ return crypto.randomBytes(Math.ceil(length/2)) .toString('hex') /** convert to hexadecimal format */ .slice(0,length); /** return required number of characters */ }; /** * hash password with sha512. * @function * @param {string} password - List of required fields. * @param {string} salt - Data to be validated. */ var sha512 = function(password, salt){ var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); var value = hash.digest('hex'); return { salt:salt, passwordHash:value }; }; /** * a function that will use the above function * to generate the hash that should be stored * in the database as user's password. */ userSchema.methods.saltHashPassword = function() { var salt = genRandomString(16); /** Gives us salt of length 16 */ var passwordData = sha512(this.password, salt); console.log('UserPassword = '+ this.password); console.log('Passwordhash = '+ passwordData.passwordHash); console.log('\nSalt = '+ passwordData.salt); return passwordData.passwordHash; } // the schema is useless so far // we need to create a model using it var User = mongoose.model('User', userSchema); // make this available to our users in our Node applications module.exports = User; 

终奌站:

 UserPassword = Chenya Passwordhash = 5bb5bf2181e2c713bae1eb49d1f3646b23db839368d38c33951774c92cec39a3c4b855aea30875e72cce6f271bdbdb27de8976c9316df09d086435b6c5629548 Salt = a88384d072b720de (node:11717) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html User saved successfully! 

您没有将callbackparameter passing到userSchema.methods.saltHashPassword而是像处理函数一样处理函数。

userSchema.methods.saltHashPassword更改为:

 userSchema.methods.saltHashPassword = function(callback) { // <-- Add callback param var salt = genRandomString(16); /** Gives us salt of length 16 */ var passwordData = sha512(this.password, salt); console.log('UserPassword = '+ this.password); console.log('Passwordhash = '+ passwordData.passwordHash); console.log('\nSalt = '+ passwordData.salt); // Your function that you passed in is called here callback(null, passwordData.passwordHash); } 

你callback的原因并不是在saltHashPassword中调用,而是在save中调用,因为Mongoose定义了该方法需要一个callback函数,该函数接受一个错误的参数和实际的返回值。

当发生错误时,预计callback会定义error handling,这是很好的做法,为什么你看到教程build议你这样做。 当你为一个Schema定义自己的方法时,你不再有这个方法,必须自己设置它。

正如你在上面的函数中看到的那样,发生了什么事情。 现在你的callback函数被传入,调用它的callback(null, passwordData.passwordHash)函数callback(null, passwordData.passwordHash)将使它执行。 如果发生了错误,可以将其保存为variables,例如err ,并将其作为callback(err, null)函数callback(err, null)

回到盐。 我没有阅读过你的教程,但重要的是将它们与用户数据一起保存在数据库中,以便在用户login时validation密码。

这里很好的资源:

密码散列加盐+胡椒或盐是否足够?

您需要salt来生成您存储在数据库中的相同散列密码。 如果您无法访问该盐,则无法知道给出的密码是否会生成相同的散列。