可以't散列密码并将其设置为mongodb模式中的字段
can't hash a password and set it to field in mongodb schema
我正在试验madhusudhan-srinivasa为node.js、express和mongodb开发的演示博客平台。。我在很大程度上基于他的实现创建了一个博客。但是,我在散列密码和创建用户方面遇到了麻烦。我已经附上了创建用户的模型和控制器,因为我不知道问题到底在哪里
我的用户创建表单有用户和密码字段,这些字段通过bodyParser传递到控制器中。
我的问题是,当我提交表单来创建用户时,我从哈希验证函数中得到一个未定义的错误,"无法获得未定义的长度。"
如果我把这个散列验证函数注释掉,就创建了一个用户。但是,当我在mongodb命令行中查看创建的用户时,它根本没有哈希字段,但名称和salt字段设置正确。然而,当我在encryptPassword()中控制台.log哈希时,它似乎输出了一个正确的哈希密码。
我已经为此工作了几个小时,完全不知道问题可能是什么
型号:
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, crypto = require('crypto')
, _ = require('underscore')
// user schema
var UserSchema = new Schema ({
name: { type: String, default: '' },
hash: { type: String, default: '' },
salt: { type: String, default: '' }
})
UserSchema
.virtual('password')
.set(function(password) {
this._password = password
this.salt = this.makeSalt()
this.hash = this.encryptPassword(password)
})
.get(function() { return this._password })
var validatePresenceOf = function (value) {
return value && value.length
}
UserSchema.path('name').validate(function(name) {
return name.length
}, 'you need a name..')
UserSchema.path('name').validate(function(name, cb) {
var User = mongoose.model('User')
if (this.isNew || this.isModified('name')) {
User.find({ name : name }).exec(function(err, users) {
cb(!err && users.length === 0)
})
} else cb(true)
}, 'name already exists..')
// i get an undefined error at the below function:
UserSchema.path('hash').validate(function(hash) {
return hash.length
}, 'you need a password...')
UserSchema.pre('save', function(next) {
if (!this.isNew) return next()
if (!validatePresenceOf(this.password)) {
next(new Error('invalid password.'))
} else {
next()
}
})
UserSchema.methods = {
// auth
authenticate: function(plaintext) {
return this.encryptPassword(plaintext) === this.hash
},
// salt
makeSalt: function() {
return crypto.randomBytes(128)
},
encryptPassword: function (password) {
if (!password) return ''
crypto.pbkdf2(password, this.salt, 2000, 128, function(err, derivedKey) {
if (err) throw err
var myhash = derivedKey.toString()
console.log('hash: ' + myhash)
return myhash
})
}
}
mongoose.model('User', UserSchema)
控制器:
exports.create = function(req, res) {
var user = new User(req.body)
user.save(function (err) {
if (err) {
return res.render('signup', {
errors: err.errors,
user: user,
title: 'SIGN UP'
})
}
req.logIn(user, function(err) {
if (err) return next(err)
return res.redirect('backend')
})
})
}
您的加密过程使用crypto.pbkdf2
,这是一个异步函数。这意味着当调用虚拟setter时,encryptPassword()将不会返回您的哈希。您的散列只在传递给crypto.pbkdf2
的回调中返回——这就是console.log在您的示例中起作用的原因。
解决这个问题的一种方法是更改encryptPassword()以使用pbkdf2的同步同级crypto.pbkdf2Sync
。链接到文档
以下示例(带有一些错误处理):
encryptPassword: function (password) {
if (!password) return ''
var encrypted
try {
encrypted = crypto.pbkdf2Sync(password, this.salt, 2000, 128).toString();
return encrypted
} catch (err) {
// Handle error
}
}
encryptPassword: function (password) {
if (!password || !this.salt)
return '';
var salt = new Buffer(this.salt, 'base64');
return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
}
相关文章:
- 如何设置html元素填充的动画
- 需要帮助设置json数组
- 如何在angularJS中编辑时,如果DB中的值为true,则设置复选框,如果值为false,则取消选中复选框
- 数组在递归方法中设置为null
- 测试MongoDB中未设置或丢失的字段
- 在document-mongoDB中设置一个字段
- MongoDB MonkAPI根据数据库请求之外可用的查找结果设置变量
- 使用点运算符设置MongoDB
- 可以't散列密码并将其设置为mongodb模式中的字段
- Expressjs Mongodb 初始连接设置困难
- MongoDB:确保只有一个文档可以将字段设置为 true
- 在节点上设置OAuth2 - 在MongoDB中处理用户的最简单方法
- 已经设置了mongodb,猫鼬等,但是当我尝试向数据库添加一些东西时,它实际上并没有添加它
- MongoDB:使用空参数设置$unset给出409错误
- mongodb的Javascript设置日期
- 如何使用JavaScript在mongodb中设置唯一id
- MongoDB:如何为多个可选值设置条件
- 在js中查询mongodb并将结果设置为变量
- 从mongodb回调中为外部变量设置一个值
- 如何通过mongoose在mongodb中设置复合主键