Nodejs bcrypt比较无法正常工作

Posted

技术标签:

【中文标题】Nodejs bcrypt比较无法正常工作【英文标题】:Nodejs bcrypt compare not working properly 【发布时间】:2019-07-10 22:30:42 【问题描述】:

我正在使用 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

请我真的很困惑,因为它假设可以工作,我搜索了谷歌但它没有帮助我,我该如何解决这个问题?提前致谢。

【问题讨论】:

通过同时连接 beforeCreate 和 beforeSave,您不是对密码进行两次散列吗?喜欢密码 -> 哈希(密码) -> 哈希(哈希(密码))?如果是这样的话,原版永远不会匹配?尝试注释掉其中一个钩子,看看它是否有任何改变。 实际上,我会摆脱 beforeSave 钩子,因为您显然不想在用户每次更新信息时都重新散列用户密码。 【参考方案1】:

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

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

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

第二个参数是一个已经散列的密码,您想将其与您的数据进行比较。

因此,您所要做的就是不对密码进行哈希处理,因为您已经对其进行哈希处理,然后将其发送到比较函数,它会被哈希两次。所以你得到一个无效的密码。

仅供参考,compare 用于并且需要处理 Promise;并且使用了compareSync,没有Promise。此外,compareSync 返回一个布尔值。

希望对你有帮助,谢谢!

【讨论】:

以上是关于Nodejs bcrypt比较无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

使用bcrypt在nodejs中进行密码加密

bcrypt 与 nodejs 比较

nodejs - 如何比较bcrypt的两个哈希密码

Bcrypt Elastic beanstalk nodejs 部署

amazon s3 deleteObjects nodejs - 无法正常工作

与nodejs无法正常工作的imagemagick