首页 > 解决方案 > Bycrpt 无法比较,总是发送空值

问题描述

我使用 Bycrpty 库来保证安全。所以我阅读了 bycrpt 官方文档。

我在注册路线上派了邮递员。它工作与否

这是成功的!像那样。

在此处输入图像描述

所以我必须在登录时比较密码,但比较总是失败。这是我的代码..

const jwt = require('jsonwebtoken');
// const { Op } = require("sequelize");
const { user } = require("../../models");
const bcrypt = require("bcrypt");
const salt = bcrypt.genSaltSync(10) ; 


  signUpController: async (req, res) => {
    const { username, email, password} = req.body;
    
    if( !(username && email && password) ){
      res.status(405).send({
        "message" : "invalid request"
      });
    }
    else{
      const userInfo = await user.findOne({
        where: {
              email: email,
              username : username
        }
      });

      if(userInfo === null){
          const newUser = await user.create({ 
            username: username, 
            email : email, 
            password:  bcrypt.hashSync(password, salt), 
          });

          let response = {  
            username: newUser.username,
            email: newUser.email,
            username: newUser.username,
            password : newUser.password
          }
       
        res.status(201).json( response );
      }
      else{
          res.status(409).send({
              "message" : "email already exist"
          });
        }
    }
  },

  login : async(req,res)=>{
    const { email, password } = req.body;

    const userInfo = await user.findOne({
      where: {
            email: email,
            password : password
      }
    });
    // console.log("req: ", req)
    if(!userInfo) {
      await res.status(400).send({data : null, message : 'not authorized'})
    }
      else {
          const data = {...userInfo.dataValues}
          console.log('password:', checkMail.password)
          bcrypt.compareSync(password, userInfo.password) ;  

          delete data.password

          const accessToken = jwt.sign(data, process.env.ACCESS_SECRET, {expiresIn : '3h'}) // create jwt 
          const refreshToken = jwt.sign(data, process.env.REFRESH_SECRET, {expiresIn : '1h'}) //  save in cookie .
       
        res.cookie("refreshToken", refreshToken) 
        res.status(200).send({data:{"accessToken": accessToken}, message:'ok'})
    }
  }

我应该怎么做才能成功?我需要建议和技巧。 在此处输入图像描述

标签: mysqlnode.js

解决方案


我有点困惑,因为您将 async/await 用于数据库库之类的某些东西,但不适用于也有承诺的 bcrypt,而是您正在使用它们的sync版本。作为第一个建议,我不会使用sync代码版本,因为它们会阻塞 eventLoop。

您的逻辑还有另一个问题 - 下面突出显示。

const jwt = require('jsonwebtoken');
// const { Op } = require("sequelize");
const { user } = require("../../models");
const bcrypt = require("bcrypt");
const salt = bcrypt.genSaltSync(10) ; 


  signUpController: async (req, res) => {
    const { username, email, password} = req.body;
    
    if( !(username && email && password) ){
      res.status(405).send({
        "message" : "invalid request"
      });
    }
    else{

      const userInfo = await user.findOne({
        where: {
              email: email,
              username : username
        }
      });
      // using email/username as unique fields to find a user and check if they already have an account
      if(userInfo === null){
          const newUser = await user.create({ 
            username: username, 
            email : email, 
            password:  bcrypt.hashSync(password, salt),
            // saving the hashed password rather than the plaintext password
          });

          let response = {  
            username: newUser.username,
            email: newUser.email,
            username: newUser.username,
            password : newUser.password
          }
          // do not under any circumstance send the password back to the user.
       
        res.status(201).json( response );
      }
      else{
          res.status(409).send({
              "message" : "email already exist"
          });
        }
    }
  },

  login : async(req,res)=>{
    const { email, password } = req.body;

    // you're trying to find a user that exists based on their email and plaintext password, but the password you've saved is the HASHED version not the plaintext version so this result will always be empty... No such user exists
    const userInfo = await user.findOne({
      where: {
            email: email,
            password : password
      }
    });
    // console.log("req: ", req)
    if(!userInfo) {
      // hence this error is present ALL THE TIME
      await res.status(400).send({data : null, message : 'not authorized'})
    }
      else {
          const data = {...userInfo.dataValues}
          console.log('password:', checkMail.password)
          bcrypt.compareSync(password, userInfo.password) ;  
          // you wouldn't need this step as you've found the user based on the password
          delete data.password

          const accessToken = jwt.sign(data, process.env.ACCESS_SECRET, {expiresIn : '3h'}) // create jwt 
          const refreshToken = jwt.sign(data, process.env.REFRESH_SECRET, {expiresIn : '1h'}) //  save in cookie .
       
        res.cookie("refreshToken", refreshToken) 
        res.status(200).send({data:{"accessToken": accessToken}, message:'ok'})
    }
  }

在我看来,这不是误解密码散列的工作原理,而是您不了解数据库中的数据。

我建议为您尝试使用的任何数据库获取一个可视化数据库浏览器。那里有许多免费和开源的!


推荐阅读