loading...

Authentication with Nodejs and mongoDB - Part 3

ebereplenty profile image NJOKU SAMSON EBERE Updated on ・4 min read

This is the third part of this authentication series with nodejs and mongoDB. If you have not checked out the previous parts, please check out part 1 and part 2.

In this part of the tutorial, we will be covering the login with jasonwebtoken (JWT). By the end, we will have seen how to crosscheck users and match the hashed password to the plain text password.

Without wasting anytime, let's jump into it.

Starter Project

If you are not coming from the previous tutorial, then you can get the starter project from here

Login Endpoint

  • Install JWT

npm i jsonwebtoken -s

  • Import JWT just below the const bcrypt = require("bcrypt"); line at the top of the app.js file like so:

const jwt = require("jsonwebtoken");

  • Just below the register endpoint, enter the following function:

app.post("/login", (request, response) => {

})

  • Let's check if the email the user enter on login exists with the following line of code:

  User.findOne({ email: request.body.email })

Next, we will use a then...catch... block to check if the email search above was successful or not

  • If it is unsuccessful, we will capture that in the catch block like so:

User.findOne({ email: request.body.email })
    .then()
    .catch((e) => {
      response.status(404).send({
        message: "Email not found",
        e,
      });
    });

  • If successful, we will compare the password entered against the hashed password in our database. We are doing this in the then... block like so:

   .then((user)=>{
      bcrypt.compare(request.body.password, user.password)
   })

We will then use a then...catch... block again to check if the comparison is successful or not

  • If the comparison is unsuccessful, we will return an error message in the catch block like so:

    .then((user)=>{
      bcrypt.compare(request.body.password, user.password)
      .then()
      .catch((error) => {
        response.status(400).send({
          message: "Passwords does not match",
          error,
        });
      })
    })

  • Let's double check if the password is correct in the then block

      .then((passwordCheck) => {

          // check if password matches
          if(!passwordCheck) {
            return response.status(400).send({
              message: "Passwords does not match",
              error,
            });
          }
        })

  • If the password matches, then create a random token with the jwt.sign() function. It takes 3 parameters i.e. jwt.sign(payload, secretOrPrivateKey, [options, callback]). You can read more here

bcrypt.compare(request.body.password, user.password)
      .then((passwordCheck) => {

          // check if password matches
          if(!passwordCheck) {
            return response.status(400).send({
              message: "Passwords does not match",
              error,
            });
          }

        //   create JWT token
        const token = jwt.sign(
          {
            userId: user._id,
            userEmail: user.email,
          },
          "RANDOM-TOKEN",
          { expiresIn: "24h" }
        );
      })

  • Finally, return a success message with the token created

.then((user)=>{
      bcrypt.compare(request.body.password, user.password)
      .then((passwordCheck) => {

          // check if password matches
          if(!passwordCheck) {
            return response.status(400).send({
              message: "Passwords does not match",
              error,
            });
          }

        //   create JWT token
        const token = jwt.sign(
          {
            userId: user._id,
            userEmail: user.email,
          },
          "RANDOM-TOKEN",
          { expiresIn: "24h" }
        );

         //   return success response
         response.status(200).send({
          message: "Login Successful",
          email: user.email,
          token,
        });
      })

  • Our Login Endpoint now looks like this:

// login endpoint
app.post("/login", (request, response) => {
  // check if email exists
  User.findOne({ email: request.body.email })

    // if email exists
    .then((user) => {
      // compare the password entered and the hashed password found
      bcrypt
        .compare(request.body.password, user.password)

        // if the passwords match
        .then((passwordCheck) => {

          // check if password matches
          if(!passwordCheck) {
            return response.status(400).send({
              message: "Passwords does not match",
              error,
            });
          }

          //   create JWT token
          const token = jwt.sign(
            {
              userId: user._id,
              userEmail: user.email,
            },
            "RANDOM-TOKEN",
            { expiresIn: "24h" }
          );

          //   return success response
          response.status(200).send({
            message: "Login Successful",
            email: user.email,
            token,
          });
        })
        // catch error if password do not match
        .catch((error) => {
          response.status(400).send({
            message: "Passwords does not match",
            error,
          });
        });
    })
    // catch error if email does not exist
    .catch((e) => {
      response.status(404).send({
        message: "Email not found",
        e,
      });
    });
});


Testing

  • Let's try to login with the credentials we registered in the last tutorial. See the random token generated on a successful login

Login Success Image

  • If email is incorrect or does not exist

Email incorrect or does not exist

  • If password is incorrect

Password incorrect

At this point, you can put hands together for yourself because you have just conquered AUTHENTICATION

πŸ‘πŸΌπŸ‘πŸΌπŸ‘πŸΌπŸ‘πŸΌπŸ‘πŸΌ

Conclusion

We began this authentication series by setting up out database in PART 1, we created a model for the user collection and a register endpoint in the PART 2 and finally, in this part, we have successfully created the login endpoint checking if users exist or not.

Congratulations!!! 🍾🍾🍾

We will look into Protecting Endpoints from unauthenticated users next. I hope to catch you there.

Meanwhile, all codes are here

GitHub logo EBEREGIT / auth-backend

This tutorial teaches how to create authentication for a user using nodejs and mongoDB

Posted on by:

ebereplenty profile

NJOKU SAMSON EBERE

@ebereplenty

I love providing solutions to real world problems. When I am not coding, I enjoy movies, hanging out and working out.

Discussion

pic
Editor guide