Bcrypt + Sequelize пароль не сохраняется как хеш в БД - PullRequest
0 голосов
/ 08 сентября 2018

Sequelize + Bcrypt не хранит пароли в БД как хэш

Как видно из заголовка, всякий раз, когда я пытаюсь сохранить пользователя в моей БД SQLite, консоль выводит пароль в виде хэша, но когда я просматриваю БД с помощью DBbrowser, я вижу пароль в виде простого текста.

Модель

// const Promise = require('bluebird')
const bcrypt = require('bcrypt')

async function hashPassword (user, options) {
  if (!user.changed('password')) {
    return 0
  }
  const SALT_FACTOR = 8
  await bcrypt.hash(user.password, SALT_FACTOR, (err, hash) => {
    if (err) {
      console.log(err)
    }
    // user.setDataValue('password', hash)
    user.password = hash
    console.log(user)
  })
}

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    email: {
      type: DataTypes.STRING,
      unique: true
    },
    password: DataTypes.STRING
  }, {
    hooks: {
      beforeSave: hashPassword,
      beforeCreate: hashPassword
    }
  })

  User.prototype.comparePassword = function (password) {
    bcrypt.compare(password, this.password, function (res, err) {
      if (res) {
        console.log(res)
      } else {
        console.log(err)
      }
    })
    return bcrypt.compare(password, this.password)
  }

  return User
}

Контроллеры

module.exports = {
  async register (req, res) {
    try {
      const user = await User.create(req.body)
      const userJson = user.toJSON()
      res.send({
        user: userJson,
        token: jwtSignUser(userJson)
      })
    } catch (err) {
      // e-mail already exists or such
      res.status(400).send({
        error: 'This email address is already in use'
      })
    }
  },
  async login (req, res) {
    try {
      // Grab user input
      const { email, password } = req.body
      const user = await User.findOne({
        where: {
          email: email
        }
      })
      // Check to see if user is in db
      if (!user) {
        res.status(403).send({
          error: 'the login information was incorrect / Not Found'
        })
      }
      // Check to see if password is valid
      const isPasswordValid = await user.comparePassword(password)
      if (!isPasswordValid) {
        return res.status(403).send({
          error: 'The login information was incorrect'
        })
      }
      // return user using toJSON()
      const userJson = user.toJSON()
      res.send({
        user: userJson,
        token: jwtSignUser(userJson)
      })
    } catch (e) {
      res.status(500).send({ error: 'An error occured attempting to login' })
      console.log(e)
    }
  }
}

Чтобы уточнить немного, всякий раз, когда я создаю пользователя, я получаю следующее:

{
    "user": {
        "id": 1,
        "email": 'test@test.com",
        "password": "$2b$08$SYYXU/GDSCFsp3MVeuqrduI0lOLHeeub7whXiaMMoVxO53YJry.1i",
        "updatedAt": "2018-09-07T22:44:12.944Z",
        "createdAt": "2018-09-07T22:44:12.944Z"
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiZW1haWwiOiJTVVBCUkhVQGxvbC5jb20iLCJwYXNzd29yZCI6IiQyYiQwOCRTWVlYVS9HRFNDRnNwM01WZXVxcmR1STBsT0xIZWV1Yjd3aFhpYU1Nb1Z4TzUzWUpyeS4xaSIsInVwZGF0ZWRBdCI6IjIwMTgtMDktMDdUMjI6NDQ6MTIuOTQ0WiIsImNyZWF0ZWRBdCI6IjIwMTgtMDktMDdUMjI6NDQ6MTIuOTQ0WiIsImlhdCI6MTUzNjM2MDI1MywiZXhwIjoxNTM2OTY1MDUzfQ.mDaeIikzUcV_AGTuklnLucx9mVyeScGpMym1y0kJnsg"
}

Что мне говорит, что БД успешно хэшировала мой пароль и сохранила его. Основная проблема для меня в этом заключается в том, что я считаю, что это приводит к тому, что функция bcrypt.compare выдает «false». Как всегда, любая информация или помощь будут с благодарностью!

Ответы [ 2 ]

0 голосов
/ 28 июня 2019

Я почти уверен, что этот ответ для вас слишком поздний, но может помочь другим найти этот же вопрос.

Основная проблема, которую я вижу, это то, как вы используете шаблон async / await. Изменение этого:

async function hashPassword (user, options) {
  if (!user.changed('password')) {
    return 0
  }
  const SALT_FACTOR = 8
  await bcrypt.hash(user.password, SALT_FACTOR, (err, hash) => {
    if (err) {
      console.log(err)
    }
    // user.setDataValue('password', hash)
    user.password = hash
    console.log(user)
  })
}

к этому, у меня сработало:

async function hashPassword(user, options) {
  if (!user.changed("password")) {
    return 0;
  }
  user.password = await bcrypt.hash(user.password, SALT_FACTOR);
}
0 голосов
/ 10 сентября 2018

Можете ли вы попробовать добавить только один крючок

hooks: {
      beforeSave: hashPassword,
    }

Потому что я думаю, что ваш пароль хешируется два раза. как beforeSave и beforeCreate оба хука выполняются.

Надеюсь, это поможет

...