DEV Community

NJOKU SAMSON EBERE
NJOKU SAMSON EBERE

Posted on • Edited on

Authentication with Nodejs and mongoDB - Part 4

This will be the final part of this authentication series with Nodejs and mongoDB. Please checkout the previous article to catch up quickly.

In this tutorial, we will be looking at protecting some routes until a user is authenticated (logged in). Stick with me.

Starter project

The starter project for this tutorial can be gotten here

  • Open your terminal and run git clone --branch login-endpoint https://github.com/EBEREGIT/auth-backend.
  • Navigate into the folder cd auth-backend.
  • Run npm install.
  • Run nodemon index. This starts up the server

Create 2 endpoints

We will need 2 endpoints in order to be able to show how authorization works. Copy the following endpoints and paste into the app.js file just before the last line.

// free endpoint
app.get("/free-endpoint", (request, response) => {
  response.json({ message: "You are free to access me anytime" });
});

// authentication endpoint
app.get("/auth-endpoint", (request, response) => {
  response.json({ message: "You are authorized to access me" });
});
Enter fullscreen mode Exit fullscreen mode

Feel free to check if the endpoints are working on postman or a browser

Create the authentication function

Here, we are creating a function that will enable us protect a particular endpoint until the user is authenticated.

  • Create a file in the root directory and name it auth.js

  • Import jasonwebtoken at the top of the file


const jwt = require("jsonwebtoken");

Enter fullscreen mode Exit fullscreen mode
  • Create and export an asynchronous function in which our authorization code will live

module.exports = async (request, response, next) => {

}

Enter fullscreen mode Exit fullscreen mode
  • In the function, we will use a try...catch... block to check if a user is logged in.

    try {

    } catch (error) {
        response.status(401).json({
            error: new Error("Invalid request!"),
          });
    }

Enter fullscreen mode Exit fullscreen mode
  • In the try{} block, let's get the authentication token from the authorization header

//   get the token from the authorization header
    const token = await request.headers.authorization.split(" ")[1];

Enter fullscreen mode Exit fullscreen mode
  • Next, let's check if the token that was generated matches the token string (RANDOM-TOKEN) we entered initially

//check if the token matches the supposed origin
    const decodedToken = await jwt.verify(
      token,
      "RANDOM-TOKEN"
    );

Enter fullscreen mode Exit fullscreen mode
  • Next, pass in the details of the decodedToken to user constant

// retrieve the user details of the logged in user
    const user = await decodedToken;

Enter fullscreen mode Exit fullscreen mode
  • Pass the user to the endpoint like so:

// pass the the user down to the endpoints here
    request.user = user;

Enter fullscreen mode Exit fullscreen mode

Finally, open the way to the endpoint like so:


// pass down functionality to the endpoint
    next();

Enter fullscreen mode Exit fullscreen mode

Our auth.js file now looks like this:


const jwt = require("jsonwebtoken");

module.exports = async (request, response, next) => {
  try {
    //   get the token from the authorization header
    const token = await request.headers.authorization.split(" ")[1];

    //check if the token matches the supposed origin
    const decodedToken = await jwt.verify(token, "RANDOM-TOKEN");

    // retrieve the user details of the logged in user
    const user = await decodedToken;

    // pass the the user down to the endpoints here
    request.user = user;

    // pass down functionality to the endpoint
    next();

  } catch (error) {
    response.status(401).json({
      error: new Error("Invalid request!"),
    });
  }
};

Enter fullscreen mode Exit fullscreen mode

Protecting the endpoint

This is the final and simplest step. We will start by importing the authentication function to the app.js file like so:


const auth = require("./auth");

Enter fullscreen mode Exit fullscreen mode

Now go to the authentication endpoint in the app.js file and add auth as a second argument like so


// authentication endpoint
app.get("/auth-endpoint", auth, (request, response) => {
  response.json({ message: "You are authorized to access me" });
});

Enter fullscreen mode Exit fullscreen mode

And that is it. That is all we need to protect that route. Let's test it out

Testing

If the user is not logged in

Alt Text

If the user is logged in

  • Login Like so:

Alt Text

  • Copy the token

  • Open a new tab on postman

  • Select bearer token in the authentication type

  • Paste the token in the token field and send the request

Alt Text

CORS

One last thing!

We need to handle CORS error. This will allow the user in the frontend to consume the APIs that we have created without any problem.

  • To do this navigate to the app.js file

  • Add the following code just below the dbConnect() line


// Curb Cores Error by adding a header here
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content, Accept, Content-Type, Authorization"
  );
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, PUT, DELETE, PATCH, OPTIONS"
  );
  next();
});

Enter fullscreen mode Exit fullscreen mode

And with this, you are a nodejs authentication champion!!!

Conclusion

This part concludes this series on authentication with nodejs and mongoDB. We have seen how to create a registration and login endpoint, how to create protection on the endpoints if we deem fit.

All codes are found here

Next, we will be looking at how to host this app on heroku. See you soon

Top comments (7)

Collapse
 
sarahleclair profile image
Sarah Leclair • Edited

Thank you so much for this tutorial.

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

You are welcome πŸ€—

Thank you for reading 😊

Collapse
 
jimmy__93 profile image
Jimmy Nguyen

Thanks a lot for this toturial.
It's really easy to understand and based on this, I can extend this into my own projects.
Thank you.

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

You are welcome πŸ€—

Collapse
 
muhammadabir profile image
Muhammad ABir

thanks a lot brother..... you made it so easy

Collapse
 
gmcamposano profile image
gmcamposano

Excellent Njoku! Thank you man

Collapse
 
ebereplenty profile image
NJOKU SAMSON EBERE

You are welcome.
I am happy you found it helpful