Node.js Bcrypt比较无法正常工作

时间:2019-02-17 09:57:41

标签: node.js sequelize.js graphql apollo bcrypt

我正在使用apollo构建具有节点qraphQl的应用程序,并且尝试创建登录页面,但是在注册并尝试登录后,我的bcrypt总是返回false,

在我的用户模型中

import bcrypt from 'bcryptjs';

const user = (sequelize, DataTypes) => {
  const User = sequelize.define('user', {    
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      unique: true,
      primaryKey: true,
      field: 'id'
    },
    fullname: DataTypes.STRING,
    username: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notEmpty: true,
      },
    },
    email: {
      type: DataTypes.STRING,
      allowedNull: false,
      validate: {
        notEmpty: true,
        isEmail: true, 
      }
    },
    password: {
      type: DataTypes.STRING,
      allowedNull: false,
      validate: {
        notEmpty: true,
        len: [7, 42],
      },
    },
    role: { 
      type: DataTypes.ENUM,
      values: ['ADMIN', 'INSTRUCTOR', 'STUDENT'],
      defaultValue: 'STUDENT'
    }
  });

User.beforeCreate(async function(user) {
  user.password = await user.generatePasswordHash(user)
});

User.beforeSave(async function(user)  {
  user.password = await user.generatePasswordHash(user)
});

User.prototype.generatePasswordHash = async function(user) {
    const saltRounds = 10;
    return await bcrypt.hash(user.password, saltRounds)
};

  User.prototype.validatePassword = async function(password) {
    console.log(this.password)
    const theReturn = await bcrypt.compare(password, this.password)
    console.log(theReturn)
    return theReturn;
  };

  User.associate = models => {
    User.hasMany(models.Message, { onDelete: 'CASCADE' });
  };

  User.findByLogin = async login => {
    let user = await User.findOne({
      where: { username: login },
    });

    if (!user) {
      user = await User.findOne({
        where: { email: login },
      });
    }

    return user;
  };

  return User;
};

export default user;

在我的用户解析器中,下面是代码

import { combineResolvers } from 'graphql-resolvers';
import Joi from 'joi'
import { isAuthenticated, isAdmin } from './authorization';
import {SignUp, SignIn} from '../functions/joi'
import {createToken} from '../functions/jwt'

export default {

  Mutation: {
    signUp: async (parent, { username, fullname, email, password, Rpassword}, { models, secret }) => {
      if(password !== Rpassword){
        return new Error('Password did not match')
      }
      var thejoi = { username, fullname, email, password }
      const checkUserEm = await models.User.find({ where: { email: email }})
      if (checkUserEm) {
          return new Error('Email address already Exist')
      }
      const checkUserUs = await models.User.find({ where: { username: username }})
      if (checkUserUs) {
          return new Error('Username already Exist')
      }

      await Joi.validate(thejoi, SignUp, {abortEarly:false})
      const user = await models.User.create({
        username, 
        fullname, 
        email,
        password,
        role:'STUDENT'
      });
      return { token: createToken(user) };
    },
    signIn: async (parent, { login, password }, { models, secret }, ) => {
      var varrh = { password }
      await Joi.validate(varrh, SignIn, {abortEarly:false})
      const user = await models.User.findByLogin(login);

      if (!user) {
        return new Error('No user found with this login credentials.');
      }

      const isValid = await user.validatePassword(password);
      if (!isValid) { 
        return new Error('Invalid password .');
      }

      return { token: createToken(user) };
    }
  },
  User: {
    messages: async (user, args, { models }) => {
      return await models.Message.findAll({
        where: {
          userId: user.id
        }
      });
    },
  },
}

当我尝试注册时,它起作用了,它将麻烦的密码存储在数据库中,但是当我尝试登录时,我收到了此错误消息

{
  "errors": [
    {
      "message": "Invalid password .",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "signIn"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Invalid password .",
            "    at signIn (C:\\Users\\De Stone Of David\\Desktop\\node projects\\vue\\cybersec\\server\\src\\resolvers\\user.js:65:16)"
          ]
        }
      }
    }
  ],
  "data": null
}

在控制台中,我得到了

Executing (default): INSERT INTO `users` (`id`,`fullname`,`username`,`email`,`password`,`role`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'nsalknlsa','stones4semper','Eloike95@gmail.com','$2a$10$eX8zvI7/EJv6N.2RzbBh9e.qKoJXtmDNDw22nAY6dixTi4btWCB6G','STUDENT','2019-02-17 09:51:44','2019-02-17 09:51:44');
Executing (default): SELECT `id`, `fullname`, `username`, `email`, `password`, `role`, `createdAt`, `updatedAt` FROM `users` AS `user` WHERE `user`.`username` = 'Eloike95@gmail.com' LIMIT 1;
Executing (default): SELECT `id`, `fullname`, `username`, `email`, `password`, `role`, `createdAt`, `updatedAt` FROM `users` AS `user` WHERE `user`.`email` = 'Eloike95@gmail.com' LIMIT 1;

$2a$10$eX8zvI7/EJv6N.2RzbBh9e.qKoJXtmDNDw22nAY6dixTi4btWCB6G
false

请问我真的很困惑,因为它可以正常工作,我已经搜索过google,但是它没有帮助我,我该如何解决这个问题?预先感谢。

1 个答案:

答案 0 :(得分:1)

好,所以我遇到了同样的问题,解决方法是这样。

在您的用户模型文件中 行:-const theReturn = await bcrypt.compare(password, this.password)

这里的密码已经用comparecompareSync进行了哈希处理,因为第一个参数应该是您在登录表单中输入的未加密的密码。

第二个参数是您要与之进行数据比较的已散列密码。

因此,您要做的就是不对密码进行哈希处理,因为您已经对密码进行了哈希处理,然后将其发送到compare函数中,因此对密码进行了两次哈希处理。这样您会得到一个无效的密码。

仅供参考,compare用于处理Promise;并且使用compareSync,而没有任何承诺。另外,compareSync返回一个布尔值。

希望能有所帮助,谢谢!