Mongoose "schema method" 回调不工作
Mongoose "schema method" callback not working
我是猫鼬和 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方法可以打印出保存成功的log信息。:
//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 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!
您没有将回调参数传递给 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
定义该方法需要一个接受参数的回调函数对于错误和实际 return 值。
发生错误时,预计回调将定义错误处理,这是一种很好的做法,也是为什么您会看到教程建议您这样做的原因。当您为 Schema
定义自己的方法时,您将不再拥有该方法并且必须自己设置它。
正如您在上面的函数中看到的那样,这就是发生的事情。现在你的回调作为参数传入 callback(null, passwordData.passwordHash)
调用它将使它执行。如果您曾经发生过错误,则可以将其保存为变量,例如err
并将其作为 callback(err, null)
传递到您的函数中
回到盐。我还没有读过你的教程,但重要的是你将它们与你的用户数据一起保存在数据库中,以便在用户登录时验证密码。
好资源在这里:
Password Hashing add salt + pepper or is salt enough?
您需要盐来生成您存储在数据库中的相同散列密码。如果您无权访问该盐,则无法知道给定的密码是否会生成相同的哈希值。
我是猫鼬和 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方法可以打印出保存成功的log信息。:
//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 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!
您没有将回调参数传递给 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
定义该方法需要一个接受参数的回调函数对于错误和实际 return 值。
发生错误时,预计回调将定义错误处理,这是一种很好的做法,也是为什么您会看到教程建议您这样做的原因。当您为 Schema
定义自己的方法时,您将不再拥有该方法并且必须自己设置它。
正如您在上面的函数中看到的那样,这就是发生的事情。现在你的回调作为参数传入 callback(null, passwordData.passwordHash)
调用它将使它执行。如果您曾经发生过错误,则可以将其保存为变量,例如err
并将其作为 callback(err, null)
回到盐。我还没有读过你的教程,但重要的是你将它们与你的用户数据一起保存在数据库中,以便在用户登录时验证密码。
好资源在这里:
Password Hashing add salt + pepper or is salt enough?
您需要盐来生成您存储在数据库中的相同散列密码。如果您无权访问该盐,则无法知道给定的密码是否会生成相同的哈希值。