简体   繁体   English

Nodejs bcrypt 比较无法正常工作

[英]Nodejs bcrypt compare not working properly

I am building an app with nodes qraphQl using apollo and I am trying to do a login page, but after signing up and and i try to sign in, my bcrypt would always return false,我正在使用 apollo 构建一个带有节点 qraphQl 的应用程序,我正在尝试创建一个登录页面,但是在注册并尝试登录后,我的 bcrypt 总是返回 false,

in my user model在我的用户模型中

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;

And in my users resolver, here is the code在我的用户解析器中,这是代码

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

when i tried to signup, it worked, it stored the hassed password in the database, but when i tried to signIn i got this error message当我尝试注册时,它起作用了,它将密码存储在数据库中,但是当我尝试登录时,我收到此错误消息

{
  "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
}

In the console i got this在控制台中我得到了这个

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

Please I am really confused because its suppose to work, i have searched google but it didn't help me, how can i solve this issue?请我真的很困惑,因为它应该可以工作,我已经搜索过谷歌,但没有帮助我,我该如何解决这个问题? Thanks in advance.提前致谢。

OK so I faced the same problem and the solution is this.好的,所以我遇到了同样的问题,解决方案是这样的。

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

here password has already hashed the thing with compare or compareSync is that the first parameter should be the unhashed password that you enter in the login form.这里密码已经用comparecompareSync compare了哈希处理,第一个参数应该是您在登录表单中输入的未哈希处理的密码。

The second parameter is an already hashed password that you want to compare your data with.第二个参数是一个已经散列的密码,您希望将其与您的数据进行比较。

So all you have to do is not hash the password, because you are already hashing it and then sending it into the compare function it gets hashed twice.所以你所要做的就是不要对密码进行散列,因为你已经在对它进行散列,然后将它发送到比较函数中,它会被散列两次。 So you get an invalid password.所以你得到一个无效的密码。

FYI, compare is used and required to handle the Promise;仅供参考,使用并需要compare来处理 Promise; and compareSync is used, without a Promise.并且使用compareSync ,没有 Promise。 Also, compareSync returns a boolean value.此外, compareSync返回一个布尔值。

Hope that helps, thanks!希望有帮助,谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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