简体   繁体   中英

bcrypt-nodejs compare function always return false

I'm having problem with bcrypt-nodejs' compare function. The compare function is returning the false value even the password is the right one. I've tried everything I could and I don't know the what is wrong with my code.

My Folder Structure

src
  -config
    -config.js
  -controller
    -AuthenticationController.js
  -models
    -index.js
    -User.js
  -policies
    -AuthenticationControllerPolicy.js
  app.js
  routes.js
 package.json

I think the problem is with the User.js in models folder.

User.js

const Promise = require('bluebird')
const bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'))

function hashPassword (user, options) {
  const SALT_FACTOR = 8

  if (!user.changed('password')) {
    return
  }

  return bcrypt
    .genSaltAsync(SALT_FACTOR)
    .then(salt => bcrypt.hashAsync(user.password, salt, null))
    .then(hash => {
      user.setDataValue('password', hash)
    })
}

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

  User.prototype.comparePassword = function (password) {
    return bcrypt.compareAsync(password, this.password)
  }

  User.associate = function (models) {
  }

  return User
}

AuthenticationController.js

const {User} = require('../models')
const jwt = require('jsonwebtoken')
const config = require('../config/config')

function jwtSignUser (user) {
  const ONE_WEEK = 60 * 60 * 24 * 7
  return jwt.sign(user, config.authentication.jwtSecret, {
    expiresIn: ONE_WEEK
  })
}

module.exports = {
  async register (req, res) {
    try {
      const user = await User.create(req.body)
      const userJson = user.toJSON()
      res.send({
        user: userJson
      })
    } catch (err) {
      res.status(400).send({
        error: 'This email account is already in use.'
      })
    }
  },
  async login (req, res) {
    try {
      const {email, password} = req.body
      const user = await User.findOne({
        where: {
          email: email
        }
      })

      console.log('user BEFORE', user)
      if (!user) {
        console.log('!user')
        return res.status(403).send({
          error: 'The login information was incorrect'
        })
      }

      console.log('user AFTER', user)

      const isPasswordValid = await user.comparePassword(password)
      console.log('isPasswordValid BEFORE : ', isPasswordValid)
      if (!isPasswordValid) {
        console.log('isPasswordValid AFTER : ', isPasswordValid)
        return res.status(403).send({
          error: 'The login information was incorrect'
        })
      }

      const userJson = user.toJSON()
      res.send({
        user: userJson,
        token: jwtSignUser(userJson)
      })
    } catch (err) {
      res.status(500).send({
        error: 'An error has occured trying to log in'
      })
    }
  }
}

route.js

const AuthenticationController = require('./controller/AuthenticationController')
const AuthenticationControllerPolicy = require('./policies/AuthenticationControllerPolicy')

module.exports = (app) => {
  app.post('/register',
    AuthenticationControllerPolicy.register,
    AuthenticationController.register)
  app.post('/login',
    AuthenticationController.login)
}

You can also check the repo if you want. GitHubRepo

The usage of bcrypt-nodejs appears to be correct. I would verify that both the password coming in and the hash in the database are what you expect them to be (particularly inside the comparePassword function) to rule out if it's a data issue or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM