9 Steps for JWT Authentication in Node.js Application

Safdar Ali - Nov 3 - - Dev Community

JWT (JSON Web Token) authentication is a widely-used approach for securing web applications. It enables secure communication and identity verification, making it ideal for APIs. In this article, we’ll implement JWT authentication in a Node.js app using MongoDB for data storage.

Let's jump right in! 🚀


🚀 Table of Contents

  1. What is JWT Authentication?
  2. 🌱 Setting Up the Project
  3. 🛠️ Connecting to MongoDB
  4. 🔒 Environment Configuration with .env File
  5. ⚙️ Setting Up the Express App
  6. 👤 Creating the User Model
  7. 🔑 Building Authentication Routes
  8. 🛡️ Securing Routes with Middleware
  9. 📊 Testing the API

What is JWT Authentication?

JWT authentication uses JSON Web Tokens to verify user identity within a web app. A JWT consists of three parts:

  1. Header: Contains the token type and encryption method.
  2. Payload: Stores user-specific information, such as username and role.
  3. Signature: Verifies the token's validity, ensuring data integrity.

The token is presented by users to access resources, acting as proof of their identity.


Step 1: 🌱 Setting Up the Project

To get started, create a new directory and initialize the project:

mkdir nodejs-jwt-auth
cd nodejs-jwt-auth
npm init -y
Enter fullscreen mode Exit fullscreen mode

Install the required dependencies:

npm install express mongoose jsonwebtoken dotenv
Enter fullscreen mode Exit fullscreen mode
  • express: Framework for building web servers.
  • mongoose: MongoDB library for handling data models.
  • jsonwebtoken: Library for generating and verifying JWTs.
  • dotenv: Manages environment variables securely.

Step 2: 🛠️ Connecting to MongoDB

Use MongoDB Atlas for cloud storage. Sign in to MongoDB Atlas and obtain your connection string.

In your .env file:

MONGODB_URL='mongodb+srv://your-username:your-password@cluster.mongodb.net/your-database'
SECRET_KEY='your_secret_key'
Enter fullscreen mode Exit fullscreen mode

Replace the placeholders with your credentials.


Step 3: 🔒 Environment Configuration with .env File

Create a .env file to store your MongoDB URL and secret key for JWTs.

In .env:

MONGODB_URL='your-mongodb-connection-string'
SECRET_KEY='your-secret-key'
Enter fullscreen mode Exit fullscreen mode

Step 4: ⚙️ Setting Up the Express App

Create index.js to configure Express and MongoDB connections:

const express = require("express");
const mongoose = require("mongoose");
require("dotenv").config();

const app = express();
const port = 3000;

app.use(express.json());

mongoose.connect(process.env.MONGODB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
}).then(() => console.log("MongoDB connected"))
  .catch(error => console.error("Connection error", error));

app.listen(port, () => console.log(`Server running on port ${port}`));
Enter fullscreen mode Exit fullscreen mode

Run the app:

node index.js
Enter fullscreen mode Exit fullscreen mode

For automatic restarts, install nodemon:

npm install -g nodemon
nodemon index.js
Enter fullscreen mode Exit fullscreen mode

Step 5: 👤 Creating the User Model

Define a User schema in models/User.js:

const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

module.exports = mongoose.model("User", userSchema);
Enter fullscreen mode Exit fullscreen mode

Step 6: 🔑 Building Authentication Routes

In routes/auth.js, define signup and login routes for creating users and generating JWT tokens.

const express = require("express");
const jwt = require("jsonwebtoken");
const User = require("../models/User");

const router = express.Router();

router.post("/signup", async (req, res) => {
  try {
    const { username, password } = req.body;
    const user = new User({ username, password });
    await user.save();
    res.status(201).json({ message: "User registered successfully" });
  } catch (error) {
    res.status(500).json({ message: "Internal Server Error" });
  }
});

router.post("/login", async (req, res) => {
  const { username, password } = req.body;
  try {
    const user = await User.findOne({ username });
    if (!user || user.password !== password) {
      return res.status(401).json({ message: "Invalid credentials" });
    }

    const token = jwt.sign({ id: user._id, username: user.username }, process.env.SECRET_KEY);
    res.json({ token });
  } catch (error) {
    res.status(500).json({ message: "Internal Server Error" });
  }
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Step 7: 🛡️ Securing Routes with Middleware

Create a middleware.js file to verify JWTs:

const jwt = require("jsonwebtoken");

function verifyJWT(req, res, next) {
  const token = req.headers["authorization"];
  if (!token) {
    return res.status(401).json({ message: "Access denied" });
  }

  jwt.verify(token, process.env.SECRET_KEY, (err, user) => {
    if (err) {
      return res.status(403).json({ message: "Invalid token" });
    }
    req.user = user;
    next();
  });
}

module.exports = verifyJWT;
Enter fullscreen mode Exit fullscreen mode

Step 8: 📊 Testing the API

  1. Signup: POST to /auth/signup with a JSON body:

    { "username": "john_doe", "password": "securepass" }
    
  2. Login: POST to /auth/login with the same credentials:

    { "username": "john_doe", "password": "securepass" }
    
  3. Accessing Protected Route: Send a GET request to /protected with the JWT token in the Authorization header.


Congratulations! You’ve now successfully implemented JWT authentication in a Node.js app. This setup secures your API routes, allowing only authenticated users to access them.

That's all for today.

And also, share your favourite web dev resources to help the beginners here!

Buy Me A Coffee

Connect with me:@ LinkedIn and checkout my Portfolio.

Explore my YouTube Channel! If you find it useful.

Please give my GitHub Projects a star ⭐️

Thanks for 32181! 🤗

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .