Home > Back-end >  NextJS and mongoose error while trying to setup login api using bcrypt
NextJS and mongoose error while trying to setup login api using bcrypt

Time:09-27

I am currently trying to setup an endpoint that first checks if the user exists, then compares the password entered to the hashed password stored in the MongoDB database. I am using NextJS, with Mongoose and Bcrypt in order to achieve this. The user model contains a function that compares the passwords. It looks like this:

UserSchema.methods.comparePassword = function(candidatePassword: string, cb: any) {
    bcrypt.compare(candidatePassword, this.password, function(err: any, isMatch: any) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};

On the login api, I am calling the function and comparing the entered password to the one in the database. Everything works as planned, while returning the appropriate JSON res and message, but I am getting an error saying API resolved without sending a response for /api/login, this may result in stalled requests. whenever I send a request to the endpoint. This is the code I am using for my login endpoint:

import dbConnect from "../../lib/dbConnect";
import User from "../../models/User"
import type { NextApiRequest, NextApiResponse } from 'next'

//installed passportjs for auth

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
    await dbConnect()
    //type of request
    const {method} = req

    if (method === "POST") {
      try {
        const user = await User.findOne({email: req.body.email}); 
        //checks if user does not exist
        if (!user) {
          res.status(400).json({error: "email not found"})
        }

        //if user exists: check password
        user.comparePassword(req.body.password, function(err, isMatch) {
          if (isMatch && !err) {
            res.status(200).json({success: "password matches"})
          }

          else {
            res.status(400).json({error: "password does not match"})
          }
        })
        
      } catch (error) {
        res.status(400).json({error: "connection error"})
      }
    }
}

CodePudding user response:

API resolved without sending a response for

that means route handler finished without a response.

you either return each res.status

return res.status(200).json({success: "password matches"})

or end it with

res.status(200).json({success: "password matches"})
res.end()

If those do not work, please convert to async/await syntax:

userSchema.methods.comparePassword = async function (candidatePassword) {
  return await bcrypt.compare(candidatePassword, this.password);
};

in Handler function

  try{
    const user = await User.findOne({email: req.body.email}); 
    //checks if user does not exist
    if (!user) {
      return res.status(400).json({error: "email not found"})
    }
   
   const isPasswordMatched = await user.comparePassword(req.body.password);

   if (!isPasswordMatched) {
      throw new Error("please enter email or password");
    }

   res.status(200).json({success: "password matches"})
  }
  • Related