2017-09-30 1 views
0

J'essaye d'effectuer une opération beforeCreate sur un modèle que j'ai créé via Sequelize. J'essaye d'avoir le mot de passe et le sel sauvés avant de créer l'utilisateur. Cependant, l'utilisateur est créé sans le mot de passe chiffré ou le sel. Je ne connais pas très bien Node.JS mais je suppose que cela a à voir avec sa nature asynchrone. Toute idée comment introduire correctement un callback pour que ma fonction create se comporte comme prévu?Sequelize: Avant de créer un crochet ne fonctionne pas comme prévu

Modèle:

'use strict'; 
 
var Promise = require("bluebird"); 
 
var bcrypt =Promise.promisifyAll(require("bcrypt-nodejs")); 
 
const SALT_ROUNDS = 10; 
 

 
module.exports = function(sequelize, DataTypes) { 
 
    var User = sequelize.define('User', { 
 
    username: { type: DataTypes.STRING, unique: true, allowNull: false, validate: { notEmpty: true } }, 
 
    email: { type: DataTypes.STRING, unique: true, allowNull: false, isEmail: true }, 
 
    phone_number: DataTypes.STRING, 
 
    password_hash: { type: DataTypes.STRING, allowNull: false, unique: true, validate: { notEmpty: true } }, 
 
    password_salt: DataTypes.STRING, 
 
    first_name: DataTypes.STRING, 
 
    last_name: DataTypes.STRING, 
 
    user_type: DataTypes.INTEGER, 
 
    two_factor_enabled: { type: DataTypes.BOOLEAN, defaultValue: false, }, 
 
    email_verified: DataTypes.DATE, 
 
    active: { type: DataTypes.BOOLEAN, defaultValue: true, }, 
 
    }, { 
 
    classMethods: { 
 
     associate: function(models) { 
 
     // associations can be defined here 
 
     }, 
 
     validPassword: function(password, passwd, callback) { 
 
     bcrypt.compare(password, passwd, function(err, isMatch) { 
 
      if (isMatch) { 
 
      return callback(null, true); 
 
      } else { 
 
      return callback(null, false); 
 
      } 
 
     }); 
 
     }, 
 
    }, 
 
    hooks: { 
 
\t beforeCreate: function(user, {}) { 
 
\t \t bcrypt.genSalt(SALT_ROUNDS, function(err, salt) { 
 
\t \t \t bcrypt.hash(user.password_hash, salt, function(){}, function(err, hash) { 
 
\t \t \t \t if (err) { 
 
\t \t \t \t \t return sequelize.Promise.reject(err); 
 
\t \t \t \t } 
 

 
\t   \t \t user.setDataValue('password_hash',hash); 
 
\t \t \t \t user.setDataValue('password_salt',salt); 
 
\t \t \t }); 
 

 
\t \t }); 
 
\t } 
 
    }, 
 
    instanceMethods: { 
 
\t generateHash: function(password) { 
 
\t \t return bcrypt.hashSync(password, bcrypt.genSaltSync(10), null); 
 
\t }, 
 
\t validPassword: function(password) { 
 
\t \t return bcrypt.compareSync(password, this.password); 
 
\t } 
 
    } 
 
    }); 
 

 
    //User.associate = (models) => { 
 
    // User.hasMany(models.UserType, { 
 
    // foreignKey: 'userId', 
 
    // as: 'userTypes' 
 
    // }); 
 
    //}; 
 

 
    return User; 
 
};

Et voici l'appel:

return db.User 
 
\t \t \t .create({ 
 
\t \t \t \t first_name: req.body.first_name, 
 
\t \t \t \t last_name: req.body.last_name, 
 
\t \t \t \t username: req.body.username, 
 
\t \t \t \t email: req.body.email, 
 
\t \t \t \t password_hash: req.body.password \t 
 
\t \t \t }) 
 
\t \t \t .then(user => res.status(201).send(user)) 
 
\t \t \t .catch(error => res.status(400).send(error)); 
 
\t \t },

Répondre

0

Personellement j'utiliser la Crypto, inclus dans node.j s: https://nodejs.org/api/crypto.html

J'ai une fonction pour créer le hachage:

function createHash(password, salt) { 
    const generatedSalt = typeof salt !== 'undefined' ? salt : crypto.randomBytes(128).toString('base64'); 
    const hmac = crypto.createHmac('sha256', generatedSalt); 
    hmac.update(password); 
    const hashedPassword = hmac.digest('hex'); 
    return { 
    salt: generatedSalt, 
    hash: hashedPassword 
    }; 
} 

Et dans mon modèle d'utilisateur:

beforeCreate: (user, options, cb) => { 
    const saltAndHash = createHash(user.password); 
    user.salt = saltAndHash.salt; 
    user.password = saltAndHash.hash; 
    return cb(null, options); 
} 

J'espère que cela vous aidera;)