簡體   English   中英

無法哈希密碼並將其設置為mongodb模式中的字段

[英]can't hash a password and set it to field in mongodb schema

我正在嘗試由madhusudhan srinivasa開發的演示博客平台,用於node.js,express和mongodb。 我主要根據他的實現創建了一個博客。 但是,我在散列密碼和創建用戶方面遇到麻煩。 我已經附加了用於創建用戶的模型和控制器,因為我不知道確切的問題出在哪里。

我的用戶創建表單具有用戶和密碼字段,這些字段通過bodyParser傳遞到控制器中。

我的問題是,當我提交表單以創建用戶時,我從哈希驗證功能中收到未定義的錯誤,“無法獲取未定義的長度”。

如果我將此哈希驗證功能注釋掉,則會創建一個用戶。 但是,當我在mongodb命令行中查看創建的用戶時,它根本沒有哈希字段,但是名稱和鹽字段設置正確。 但是,當我在console.log內cryptoPassword()中的哈希值時,似乎輸出了正確哈希值的密碼。

我已經為此工作了幾個小時,完全不知道可能是什么問題。

模型:

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 ,這是一個異步函數。 這意味着在調用虛擬設置器時,encryptPassword()將不會返回您的哈希。 您的哈希只會在傳遞給crypto.pbkdf2的回調內部返回-這就是為什么console.log在您的示例中起作用的原因。

解決此問題的一種方法是更改​​cryptoPassword()以利用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');
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM