Bcrypt + Sequelize密码未另存为哈希在数据库中

时间:2018-09-07 23:14:09

标签: express hash sequelize.js bcrypt

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 :(得分:0)

可以请您仅添加一个挂钩

hooks: {
      beforeSave: hashPassword,
    }

因为我认为您的密码被哈希了两次。如beforeSave和beforeCreate一样,两个钩子都将执行。

希望有帮助

答案 1 :(得分:0)

我很确定这个答案对您来说太迟了,但可能会帮助其他人解决这个问题。

我可以看到的主要问题是如何使用异步/等待模式。改变这个:

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);
}