복붙노트

[MONGODB] 몽구스 암호 해싱

MONGODB

몽구스 암호 해싱

나는 몽구스를 사용하여 MongoDB에 계정을 저장할 수있는 좋은 방법을 찾고 있어요.

내 문제는 다음과 같습니다 암호를 비동기 적으로 해시됩니다. 그것은 단지 동기 작동하기 때문에 세터 여기서 일 못해.

나는 두 가지 방법에 대해 생각 :

이 문제에 대한 좋은 솔루션이 있습니까?

해결법

  1. ==============================

    1.MongoDB의 블로그는 사용자 인증을 구현하는 방법을 자세히 훌륭한 포스트를 가지고있다.

    MongoDB의 블로그는 사용자 인증을 구현하는 방법을 자세히 훌륭한 포스트를 가지고있다.

    http://blog.mongodb.org/post/32866457221/password-authentication-with-mongoose-part-1

    다음은 위의 링크에서 직접 복사됩니다 :

    var mongoose = require('mongoose'),
        Schema = mongoose.Schema,
        bcrypt = require('bcrypt'),
        SALT_WORK_FACTOR = 10;
    
    var UserSchema = new Schema({
        username: { type: String, required: true, index: { unique: true } },
        password: { type: String, required: true }
    });
    
    
    UserSchema.pre('save', function(next) {
        var user = this;
    
        // only hash the password if it has been modified (or is new)
        if (!user.isModified('password')) return next();
    
        // generate a salt
        bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
            if (err) return next(err);
    
            // hash the password using our new salt
            bcrypt.hash(user.password, salt, function(err, hash) {
                if (err) return next(err);
    
                // override the cleartext password with the hashed one
                user.password = hash;
                next();
            });
        });
    });
    
    UserSchema.methods.comparePassword = function(candidatePassword, cb) {
        bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
            if (err) return cb(err);
            cb(null, isMatch);
        });
    };
    
    module.exports = mongoose.model('User', UserSchema);
    
    var mongoose = require(mongoose),
        User = require('./user-model');
    
    var connStr = 'mongodb://localhost:27017/mongoose-bcrypt-test';
    mongoose.connect(connStr, function(err) {
        if (err) throw err;
        console.log('Successfully connected to MongoDB');
    });
    
    // create a user a new user
    var testUser = new User({
        username: 'jmar777',
        password: 'Password123';
    });
    
    // save user to database
    testUser.save(function(err) {
        if (err) throw err;
    });
    
    // fetch user and test password verification
    User.findOne({ username: 'jmar777' }, function(err, user) {
        if (err) throw err;
    
        // test a matching password
        user.comparePassword('Password123', function(err, isMatch) {
            if (err) throw err;
            console.log('Password123:', isMatch); // -> Password123: true
        });
    
        // test a failing password
        user.comparePassword('123Password', function(err, isMatch) {
            if (err) throw err;
            console.log('123Password:', isMatch); // -> 123Password: false
        });
    });
    
  2. ==============================

    2.이것을 사용할 수 있습니다 ES6 + 구문을 사용하고자하는 사람들을 위해 -

    이것을 사용할 수 있습니다 ES6 + 구문을 사용하고자하는 사람들을 위해 -

    const bcrypt = require('bcryptjs');
    const mongoose = require('mongoose');
    const { isEmail } = require('validator');
    
    const { Schema } = mongoose;
    const SALT_WORK_FACTOR = 10;
    
    const schema = new Schema({
      email: {
        type: String,
        required: true,
        validate: [isEmail, 'invalid email'],
        createIndexes: { unique: true },
      },
      password: { type: String, required: true },
    });
    
    schema.pre('save', async function save(next) {
      if (!this.isModified('password')) return next();
      try {
        const salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
        this.password = await bcrypt.hash(this.password, salt);
        return next();
      } catch (err) {
        return next(err);
      }
    });
    
    schema.methods.validatePassword = async function validatePassword(data) {
      return bcrypt.compare(data, this.password);
    };
    
    const Model = mongoose.model('User', schema);
    
    module.exports = Model;
    
  3. ==============================

    3.나는이 사용자 몽구스와 bcrypt에 의해 좋은 방법이라고 생각!

    나는이 사용자 몽구스와 bcrypt에 의해 좋은 방법이라고 생각!

    /**
     * Module dependences
    */
    
    const mongoose = require('mongoose');
    const Schema = mongoose.Schema;
    const bcrypt = require('bcrypt');
    const SALT_WORK_FACTOR = 10;
    
    // define User Schema
    const UserSchema = new Schema({
        username: {
            type: String,
            unique: true,
            index: {
                unique: true
            }
        },
        hashed_password: {
            type: String,
            default: ''
        }
    });
    
    // Virtuals
    UserSchema
        .virtual('password')
        // set methods
        .set(function (password) {
            this._password = password;
        });
    
    UserSchema.pre("save", function (next) {
        // store reference
        const user = this;
        if (user._password === undefined) {
            return next();
        }
        bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
            if (err) console.log(err);
            // hash the password using our new salt
            bcrypt.hash(user._password, salt, function (err, hash) {
                if (err) console.log(err);
                user.hashed_password = hash;
                next();
            });
        });
    });
    
    /**
     * Methods
    */
    UserSchema.methods = {
        comparePassword: function(candidatePassword, cb) {
            bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
                if (err) return cb(err);
                cb(null, isMatch);
            });
        };
    }
    
    module.exports = mongoose.model('User', UserSchema);
    
    signup: (req, res) => {
        let newUser = new User({
            username: req.body.username,
            password: req.body.password
        });
        // save user
        newUser.save((err, user) => {
            if (err) throw err;
            res.json(user);
        });
    }
    

    결과

  4. ==============================

    4.몽구스 공식 솔루션은 모델이 혼란을 일으킬 수 verifyPass 방법을 사용하기 전에 저장해야합니다. 당신을 위해 일을 다음시겠습니까? (내가 대신 bcrypt의 scrypt을 사용하고 있습니다).

    몽구스 공식 솔루션은 모델이 혼란을 일으킬 수 verifyPass 방법을 사용하기 전에 저장해야합니다. 당신을 위해 일을 다음시겠습니까? (내가 대신 bcrypt의 scrypt을 사용하고 있습니다).

    userSchema.virtual('pass').set(function(password) {
        this._password = password;
    });
    
    userSchema.pre('save', function(next) {
        if (this._password === undefined)
            return next();
    
        var pwBuf = new Buffer(this._password);
        var params = scrypt.params(0.1);
        scrypt.hash(pwBuf, params, function(err, hash) {
            if (err)
                return next(err);
            this.pwHash = hash;
            next();
        });
    });
    
    userSchema.methods.verifyPass = function(password, cb) {
        if (this._password !== undefined)
            return cb(null, this._password === password);
    
        var pwBuf = new Buffer(password);
        scrypt.verify(this.pwHash, pwBuf, function(err, isMatch) {
            return cb(null, !err && isMatch);
        });
    };
    
  5. ==============================

    5.CONST의 bcrypt는 = ( 'bcrypt')를 요구; CONST saltRounds = 5; CONST 염 = bcrypt.genSaltSync (saltRounds); module.exports = (암호) => {   반환 bcrypt.hashSync (비밀번호, 소금); }

    CONST의 bcrypt는 = ( 'bcrypt')를 요구; CONST saltRounds = 5; CONST 염 = bcrypt.genSaltSync (saltRounds); module.exports = (암호) => {   반환 bcrypt.hashSync (비밀번호, 소금); }

    CONST 몽구스 =은 ( '몽구스')를 필요 CONST 스키마 = mongoose.Schema const를 hashPassword = 필요 ( '../ 도우미 / hashPassword') const를 userSchema = 새로운 스키마 ({   이름 : 문자열,   이메일 : {     입력 문자열을,     일치 : [/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@를 \ "] +) *) | (\"+ \ ")) @ ((\ [0-9] {1,3} \ [0-9] {1,3} \ [0-9... {1,3} \ [0-9] {1,3} \]) |. (. ([A-ZA-Z는 \ -0-9] + \) + [A-ZA-Z] {2 })) $ /`] 유효한 이메일 address`을 기입하십시오,     확인: {       검증 : 함수 () {         새로운 약속 ((입술, REJ)을 반환 => {           User.findOne ({이메일 : this.email는 _ID : {$ NE : this._id}})               그 때는 (데이터 => {                   경우 (데이터) {                       고해상도 (거짓)                   } 다른 {                       고해상도 (참)                   }               })               .catch (ERR => {                   고해상도 (거짓)               })         })       }, 메시지 : '이메일은 이미 촬영'     }   },   암호 : {     입력 문자열을,     필요 : 사실, '비밀번호가 필요합니다']   } }); userSchema.pre는 ({), 다음 기능 ( '저장'   경우 (this.password) {       this.password = hashPassword (this.password)   }   다음() }) const를 사용 = mongoose.model ( '사용자', userSchema) module.exports = 사용자

  6. ==============================

    6.일부 연구는 내가 발견 한 후 나는 후크를 사용하는 것이 더 좋을 것 같아요

    일부 연구는 내가 발견 한 후 나는 후크를 사용하는 것이 더 좋을 것 같아요

    http://mongoosejs.com/docs/middleware.html

    어디는 말한다 :

    사용 사례:

    비동기 기본값

    나는이 캡슐화하고 계정 만 암호로 저장 될 수 있도록 할 수 있기 때문에 나는이 솔루션을 선호합니다.

  7. ==============================

    7.또 다른 방법이 사용 virtuals에와 인스턴스 메소드를 할 수 :

    또 다른 방법이 사용 virtuals에와 인스턴스 메소드를 할 수 :

    /**
     * Virtuals
     */
    schema.virtual('clean_password')
        .set(function(clean_password) {
            this._password = clean_password;
            this.password = this.encryptPassword(clean_password);
        })
        .get(function() {
            return this._password;
        });
    
    schema.methods = {
    
        /**
         * Authenticate - check if the passwords are the same
         *
         * @param {String} plainText
         * @return {Boolean}
         * @api public
         */
        authenticate: function(plainPassword) {
            return bcrypt.compareSync(plainPassword, this.password);
        },
    
        /**
         * Encrypt password
         *
         * @param {String} password
         * @return {String}
         * @api public
         */
        encryptPassword: function(password) {
            if (!password)
                return '';
    
            return bcrypt.hashSync(password, 10);
        }
    };
    

    그냥 그 일을 할 것, 가상을 같은 모델을 저장합니다.

    var user = {
        username: "admin",
        clean_password: "qwerty"
    }
    
    User.create(user, function(err,doc){});
    
  8. ==============================

    8.

    const mongoose = require('mongoose');
    var bcrypt = require('bcrypt-nodejs');
    SALT_WORK_FACTOR = 10;
    
    const userDataModal = mongoose.Schema({
        username: {
            type: String,
            required : true,
            unique:true
        },
        password: {
            type: String,
            required : true
        }
    
    });
    
    userDataModal.pre('save', function(next) {
        var user = this;
    
        // only hash the password if it has been modified (or is new)
        if (!user.isModified('password')) return next();
    
        // generate a salt
        bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
            if (err) return next(err);
    
            // hash the password using our new salt
            bcrypt.hash(user.password, salt, null, function(err, hash) {
                if (err) return next(err);
    
                // override the cleartext password with the hashed one
                user.password = hash;
                next();
            });
        });
    });
    
    userDataModal.methods.comparePassword = function(candidatePassword, cb) {
        bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
            if (err) return cb(err);
            cb(null, isMatch);
        });
    };
    
    
    // Users.index({ emaiId: "emaiId", fname : "fname", lname: "lname" });
    
    const userDatamodal = module.exports = mongoose.model("usertemplates" , userDataModal)
    
    
    
    //inserting document
         userDataModel.findOne({ username: reqData.username }).then(doc => {
                console.log(doc)
                if (doc == null) {
                    let userDataMode = new userDataModel(reqData);
                   // userDataMode.password = userDataMode.generateHash(reqData.password);
                    userDataMode.save({new:true}).then(data=>{
                              let obj={
                                  success:true,
                                  message: "New user registered successfully",
                                  data:data
                              }
                                resolve(obj)
                    }).catch(err=>{
                                    reject(err)
                    })
    
                }
                else {
                    resolve({
                        success: true,
                        docExists: true,
                        message: "already user registered",
                        data: doc
                    }
                    )
                }
    
            }).catch(err => {
                console.log(err)
                reject(err)
            })
    
    //retriving and checking
          // test a matching password
                    user.comparePassword(requestData.password, function(err, isMatch) {
                        if (err){ 
    
                            reject({
                                'status': 'Error',
                                'data': err
                            });
    
                            throw err;
                        } else  {
                            if(isMatch){
    
                                resolve({   
                                    'status': true,
                                    'data': user,
                                    'loginStatus' : "successfully Login"
                                });
    
                                console.log('Password123:', isMatch); // -&gt; Password123: true
    
                            }
    
  9. from https://stackoverflow.com/questions/14588032/mongoose-password-hashing by cc-by-sa and MIT license