How to Create an Authentication API with JWT Token in Node.js

How to Create an Authentication API with JWT Token in Node.js. In this tutorial, we guide you through the steps to create a Node.js authentication API with JWT Tokens that are used in your web applications.

As you may know, JWT (JSON Web Token) is a popular authentication mechanism that allows users to securely transmit information between parties. With Node.js, we easily create an authentication API that uses JWT Tokens to authenticate users and secure their data.

What is Authentication and Authorization?

When it comes to security and gaining access to a system, authentication and authorization are crucial. It’s important to note that gaining entry into a system is just the first step, also known as authentication. What you’re allowed to do once inside is determined by the authorization process. This is similar to gaining entry into a house versus what you’re permitted to do once you’re inside.

Authentication

Verifying a user’s identity through credentials is called authentication. If the credentials are legitimate, the authorization process begins. This process always follows the authentication procedure. We all perform authentication daily, such as logging into our computers at work or websites at home. Most internet-connected devices require proof of identity through credentials.

Authorization

It’s important to remember that gaining access to a system is just the first step, and what you’re able to do once inside is determined by the authorization process. This process allows authenticated users to access resources by determining whether they have permission to do so. By granting or denying specific licenses to an authenticated user, authorization enables the control of access privileges.

So, authorization occurs after the system authenticates your identity, granting you complete access to resources such as information, files, databases, funds, places, and anything else. That said, authorization affects your capacity to access the system and the extent to which you can do so.

Have you heard of JSON Web Tokens (JWT)? They are an open industry standard for representing claims between two parties. Use jwt.io to decode, verify, and produce JWT. The great thing about JWT is that it specifies a compact and self-contained method for communicating information as a JSON object between two parties. It’s signed, so the information is checked and trusted. Sign JWTs using a secret (using the HMAC algorithm) or an RSA or ECDSA public/private key combination. Do you want to see some examples of how to use them?

How to Create an Authentication API with JWT Token in Node.js

In this section, we walk you through the process of creating an authentication API with JWT token in Node.js.

Prerequisites

Before we begin, make sure you have the following prerequisites installed on your system:

  • A code editor (e.g., Visual Studio Code)
  • MongoDB (or any other database of your choice)

Step 1- Create a directory and initialize the npm

To begin, let’s set up our project by opening Visual Studio Code from a directory of our choice using the terminal. Then, open the Windows PowerShell, Create a directory and initialize npm by typing the following command:

				
					mkdir jwt-project
cd jwt-project
npm init -y
				
			

Step 2 - Create files and directories

In step 1, we initialized npm with the command npm init -y, which automatically created a package.json. We need to create the model, middleware, config directory and their files, for example, user.js,a uth.js, database.js using the commands below.

				
					mkdir model middleware config
touch config/database.js middleware/auth.js model/user.js
				
			

We are now create the index.js and app.js files in the root directory of our project with the command.

				
					touch app.js index.js
				
			

Your whole project directory structure is now shown in the below image:

Step 3 - Install dependencies

Now, we install several dependencies like mongoose, jsonwebtoken, express dotenv bcryptjs and development dependency like nodemon to restart the server as we make changes automatically.

We also need to install Mongoose because I am using MongoDB in this tutorial. Then, validate user credentials against what we have in our database. So the whole authentication process is not limited to the database we’ll be using in this article.

				
					npm install mongoose express jsonwebtoken dotenv bcryptjs
				
			

You see the following screen.

Step 4 - Create a Node.js server and connect your database

Now, let’s create our Node.js server and connect our database by adding the following snippets to your app.js, index.js , database.js .env in that order.

First, edit your database.js file and add the following code.

				
					const mongoose = require("mongoose");
const { MONGO_URI } = process.env;
exports.connect = () => {
 // Connecting to the database
 mongoose
   .connect(MONGO_URI, {
     useNewUrlParser: true,
     useUnifiedTopology: true,
     useCreateIndex: true,
     useFindAndModify: false,
   .then(() => {
     console.log("Successfully connected to database");
   .catch((error) => {
console.log("database connection failed. exiting now...");
console.error(error)
process.exit(1);
 });
});

};

				
			

Save and close the file then edit your app.js file and add the following content.

				
					require("dotenv").config();
require("./config/database").connect();
const express = require("express");
const app = express();
app.use(express.json());// Logic goes here
module.exports = app;

				
			

Then edit your index.js file and add the following code.

				
					const http = require("http");
const app = require("./app");
const server = http.createServer(app);
const { API_PORT } = process.env;
const port = process.env.PORT || API_PORT;
// server listening 

server.listen(port, () => {
console.log(`Server running on port ${port}`);

});

				
			

If you notice, our file needs some environment variables. You can create a new .env file if you haven’t already and add your variables before starting our application.

Edit your .env file and add the following configuration.

				
					API_PORT=4001
MONGO_URI=//your-database-host
				
			

To start your server, edit the script object in our package.json to look like the one shown below.

				
					"script": {
	"start": "node index.js",
	"dev": "nodemon index.js",
	"test": "echo \"Error: no test specified\" && exit 1"
	},
				
			

The snippet above has been successfully inserted into app.js, index.js, and database.js. First, we built our node.js server in index.js and imported the app.js file with routes configured.

Then, as indicated in database.js, we used mongoose to create a connection to our database.

Finally, execute the following command.

				
					npm run dev
				
			

Both the server and the database should be up and running without crashing.

Step 5 - Create user model and route

We define our schema for the user details when signing up for the first time and validate them against the saved credentials when logging in.

Add the following snippet to user.js inside the model folder.

				
					const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({

 first_name: { type: String, default: null },

 last_name: { type: String, default: null },

 email: { type: String, unique: true },

 password: { type: String },

 token: { type: String },

});
});
// Login
module.exports = mongoose.model("user", userSchema);

				
			

Now let’s create the routes for register and login, respectively.

In app.js in the root directory, add the following snippet for the registration and login.

				
					// importing user context
const User = require("./model/user");
// Register
app.post("/register", (req, res) => {
// our register logic goes here...
app.post("/login", (req, res) => {

// our login logic goes here

});

				
			

Save and close the file when you are done.

Step 6 - Implement register and login functionality

We are implementing these two routes in our application. We will be using JWT to sign the credentials and bycrypt to encrypt the password before storing them in our database.

From the /register route, we will:

  • Get user input.
  • Validate user input.
  • Encrypt the user password.
  • Validate if the user already exists.
  • Create a user in our database.
  • And finally, create a signed JWT token.

Edit the app.js file and modify the /register route structure we created earlier to look as shown below.

				
					// ...
app.post("/register", async (req, res) => {
 // Our register logic starts here
 try {
   // Get user input
   const { first_name, last_name, email, password } = req.body;
   // Validate user input
   if (!(email && password && first_name && last_name)) {

     res.status(400).send("All input is required");

   }

   // check if user already exist
   // Validate if user exist in our database
   const oldUser = await User.findOne({ email });
   if (oldUser) {
     return res.status(409).send("User Already Exist. Please Login");
   }
//Encrypt user password
   encryptedPassword = await bcrypt.hash(password, 10);
   // Create user in our database
   const user = await User.create({
     first_name,
     last_name,
     email: email.toLowerCase(), // sanitize: convert email to lowercase
     password: encryptedPassword,   });
   // Create token
   const token = jwt.sign(
     { user_id: user._id, email },
     process.env.TOKEN_KEY,
     {
       expiresIn: "2h",
     }
   );
   // save user token
  user.token = token;
   // return new user
   res.status(201).json(user);
 } catch (err) {
   console.log(err);
 }
 // Our register logic ends here
});
// ...

				
			

Using Postman to test the endpoint, we’ll get the response shown below after successful registration.

For the /login route, we will:

  • Get user input.
  • Validate user input.
  • Also, validate if the user exists.
  • Verify the user password against the password we saved earlier in our database.
  • And finally, create a signed JWT token.

Modify the /login route structure we created earlier to look like shown below.

				
					app.post("/login", async (req, res) => {
 // Our login logic starts here
 try {
   // Get user input
   const { email, password } = req.body;
   // Validate user input
   if (!(email && password)) {
     res.status(400).send("All input is required");
   }
   // Validate if user exist in our database
   const user = await User.findOne({ email });
   if (user && (await bcrypt.compare(password, user.password))) {
     // Create token
     const token = jwt.sign(
       { user_id: user._id, email },
       process.env.TOKEN_KEY,
       {
         expiresIn: "2h",} );

     // save user token
     user.token = token;
     // user
     res.status(200).json(user);  }

   res.status(400).send("Invalid Credentials");

 } catch (err) {
   console.log(err);
 }

 // Our register logic ends here

});

				
			

After conducting a successful login test using Postman, the response displayed below will be received.

Step 7 - Create middleware for authentication

We can successfully create and log in as a user. Still, we’ll create a route that requires a user token in the header, which is the JWT token we generated earlier.

Edit the auth.js file and add the following snippet.

				
					const jwt = require("jsonwebtoken");
const config = process.env;
const verifyToken = (req, res, next) => {
 const token =
   req.body.token || req.query.token || req.headers["x-access-token"];
 if (!token) {
   return res.status(403).send("A token is required for authentication");
 }
 try {
   const decoded = jwt.verify(token, config.TOKEN_KEY);
   req.user = decoded;

 } catch (err) {
   return res.status(401).send("Invalid Token");
 }
 return next();

};
module.exports = verifyToken;

				
			

Now let’s create the /welcome route and update app.js with the following snippet to test the middleware.

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

app.post("/welcome", auth, (req, res) => {

 res.status(200).send("Welcome ");

});


				
			

You can see the below image for a response:

Thank you for reading How to Create an Authentication API with JWT Token in Node.js. It is time to conclude.

How to Create an Authentication API with JWT Token in Node.js Conclusion

In this tutorial, we explained about how authentication and authorization works. Then, showed you how to use JWT for authentication and authorization when developing an API in Node.js. I hope you have now a solid foundation for building secure authentication systems for your own projects. While this is a simplified example, it provides a foundation that you can build upon to create more robust and secure authentication systems for your web applications.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x