skip to Main Content

So i am trying to save user details to my mongodb database. I was able to successfully save the data prior to hashing the entered password with bcrypt

I am not able to save the userdetails to the database after hashing the password.

Here is my code

const router = require("express").Router();
const User = require("../models/user");
const bcrypt = require("bcryptjs");

router.post("/register", async (req, res) => {
  bcrypt.genSalt(10, function (err, Salt) {
    bcrypt.hash(req.body.password, Salt, function (err, hash) {
      if (err) {
        return console.log("Cannot Encrypt");
      }

      var hashedPassword = hash;
      console.log(hashedPassword);

      var newUser = new User({
        username: req.body.username,
        email: req.body.email,
        password: hashedPassword,
      });

      try {
        const user = newUser.save();
        res.status(200).json({
            status: "user created successfully",
            message: {
                user: user
            }
        });
      } catch (error) {
        res.status(404).json({
          status: "fail",
          message: error,
        });
      }
    });
  });
});

module.exports = router;

Here are the postman screenshots and a screenshot of the VSCode terminal.

VSCode_terminal

PostmanAPI_screenshot

2

Answers


  1. The issue seems to be related to the asynchronous nature of the code. The bcrypt.hash function is asynchronous and returns a hashed password in the callback function. However, the code is not properly handling the asynchronous behavior, and the newUser.save() line is executed before the hashing is completed.

    To fix this, you can wrap the code after hashing the password inside a Promise and use async/await to properly handle the asynchronous behavior. Here’s an updated version of your code:

    const router = require("express").Router();
    const User = require("../models/user");
    const bcrypt = require("bcryptjs");
    
    router.post("/register", async (req, res) => {
      try {
        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash(req.body.password, salt);
    
        var newUser = new User({
          username: req.body.username,
          email: req.body.email,
          password: hashedPassword,
        });
    
        const user = await newUser.save();
    
        res.status(200).json({
          status: "user created successfully",
          message: {
            user: user,
          },
        });
      } catch (error) {
        res.status(404).json({
          status: "fail",
          message: error,
        });
      }
    });
    
    module.exports = router;
    

    In this updated code, the bcrypt.genSalt and bcrypt.hash functions are awaited to ensure that the hashing is completed before proceeding. The newUser.save() line is also awaited to ensure that the user is saved to the database before sending the response.

    By using async/await, you can write the code in a more synchronous-like style while handling the asynchronous operations correctly.

    Login or Signup to reply.
  2. Issue is Due to Not using Async/ Await while encrypt a password , but there is a significant way by which you can perform your operations without using await with Error Handling by use of promise

    const router = require("express").Router();
    const User = require("../models/user");
    const bcrypt = require("bcryptjs");
    
    router.post("/register", (req, res) => {
      bcrypt.genSalt(10)
        .then((salt) => {
    
          //use promise
          bcrypt.hash(req.body.password, salt)
            .then((hashedPassword) => {
              var newUser = new User({
                username: req.body.username,
                email: req.body.email,
                password: hashedPassword,
              });
    
              newUser.save()
                .then((user) => {
                  res.status(200).json({
                    status: "user created successfully",
                    message: {
                      user: user,
                    },
                  });
                })
                .catch((error) => {
                  res.status(404).json({
                    status: "fail",
                    message: error,
                  });
                });
            })
            .catch((error) => {
              res.status(404).json({
                status: "fail",
                message: error,
              });
            });
        })
        .catch((error) => {
          //handle error incase of failure
          res.status(404).json({
            status: "fail",
            message: error,
          });
        });
    });
    
    module.exports = router;

    I have replaced the await keyword with then and catch to handle the promises returned by the asynchronous functions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search