2016-08-20 65 views
1

我是新來的貓鼬和node.js。我嘗試按照本教程:https://scotch.io/tutorials/using-mongoosejs-in-node-js-and-mongodb-applications#sample-model-for-users貓鼬「架構方法」回調不起作用

在我的切入點index.js,席力圖召「chenya.saltHashPassword(功能(ERR,passwordHash)」這實際上是所謂的user.js的,因爲user.js的能打印出三個日誌消息;但是,對於這種方法index.js根本沒有通話日誌消息相反,保存方法可以打印出日誌消息,指示保存成功:

//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: '[email protected]', 
    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!'); 
    } 
}); 

在我的用戶。 .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 i.e 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! 

回答

2

你不能傳遞一個回調參數爲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); 
} 

,你的回調並沒有在saltHashPassword叫,但被稱爲save是因爲Mongoose定義方法需要一個回調函數,它的參數的原因錯誤和實際返回值。

發生錯誤時,預計回調將定義錯誤處理,這是很好的做法,爲什麼你看到教程建議你也這樣做。當你爲Schema定義自己的方法時,你不再擁有這個方法,必須自己設置它。

所以,你可以在上面的函數中看到,這就是發生了什麼。現在你的回調被傳入,調用它的參數callback(null, passwordData.passwordHash)將使它執行。如果您發生錯誤,您可以將其保存爲變量,例如err並將其作爲您的功能callback(err, null)

回到鹽。我沒有看過你的教程,但你將它們保存在您的用戶數據一起數據庫,以便密碼可以驗證這一點很重要,當在

良好的資源在這裏用戶登錄:

Password Hashing add salt + pepper or is salt enough?

您需要salt來生成存儲在數據庫中的相同散列密碼。如果您無法訪問該鹽,則無法知道給出的密碼是否會生成相同的散列。