Build a Complete Full-Stack Authentication System using Node.js, Express, MongoDB, and JWT

Build a complete full-stack authentication system using Node.js, Express, MongoDB & JWT with step-by-step beginner-friendly tutorial.


In this tutorial, you will learn how to build a complete Full Stack Authentication System using modern backend technologies like Node.js, Express, MongoDB, and JWT. This project is widely used in real-world applications such as dashboards, SaaS apps, and e-commerce platforms.


📌 Project Overview

Authentication is one of the most important parts of any web application. It ensures that only authorized users can access protected resources. In this project, we will build a secure authentication system with the following features:

  • User registration (Signup)
  • User login system
  • Password hashing using bcrypt
  • JWT token-based authentication
  • Protected routes using middleware
  • Logout functionality

We will also connect a frontend using HTML and JavaScript Fetch API to interact with backend APIs.


⚙️ Step 1: Project Setup (Node.js Initialization)

First, create a new folder and initialize Node.js project.


mkdir auth-system
cd auth-system
npm init -y

Install required dependencies:


npm install express mongoose bcryptjs jsonwebtoken cors dotenv

These packages help us build a secure backend system.


🚀 Step 2: Creating Express Server

Now create a file called server.js and set up a basic Express server.


const express = require("express");
const app = express();
const cors = require("cors");

app.use(express.json());
app.use(cors());

app.get("/", (req, res) => {
    res.send("Server is running...");
});

app.listen(5000, () => {
    console.log("Server started on port 5000");
});

At this point, your backend server is ready.


🗄️ Step 3: Connecting MongoDB Database

We will use MongoDB to store user data securely.


const mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/authDB")
.then(() => console.log("MongoDB Connected"))
.catch(err => console.log(err));

Make sure MongoDB is installed and running on your system.


👤 Step 4: Creating User Schema

We define how user data will be stored in the database.


const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
    username: String,
    email: String,
    password: String
});

module.exports = mongoose.model("User", userSchema);

🔐 Step 5: Password Hashing using bcrypt

We never store plain passwords. Instead, we hash them using bcrypt.


const bcrypt = require("bcryptjs");

const hashedPassword = await bcrypt.hash(password, 10);

This makes your system much more secure.


🔑 Step 6: JWT Authentication System

JWT (JSON Web Token) is used to securely transfer user authentication data.


const jwt = require("jsonwebtoken");

function createToken(user) {
    return jwt.sign({ id: user._id }, "secretKey", { expiresIn: "1h" });
}

Figure-1: JWT Token Generation Process 


📝 Step 7: Signup API Route


app.post("/signup", async (req, res) => {
    const { username, email, password } = req.body;

    const hashedPassword = await bcrypt.hash(password, 10);

    const user = new User({
        username,
        email,
        password: hashedPassword
    });

    await user.save();
    res.send("User Registered Successfully");
});

🔓 Step 8: Login API Route


app.post("/login", async (req, res) => {
    const { email, password } = req.body;

    const user = await User.findOne({ email });

    if (!user) return res.send("User not found");

    const isMatch = await bcrypt.compare(password, user.password);

    if (!isMatch) return res.send("Invalid credentials");

    const token = jwt.sign({ id: user._id }, "secretKey", { expiresIn: "1h" });

    res.json({ token });
});

🛡️ Step 9: Middleware for Protected Routes

Middleware checks if user is authenticated before accessing protected routes.


function verifyToken(req, res, next) {
    const token = req.headers["authorization"];

    if (!token) return res.send("Access denied");

    try {
        jwt.verify(token, "secretKey");
        next();
    } catch {
        res.send("Invalid token");
    }
}

🌐 Step 10: Frontend Integration (HTML + Fetch API)


fetch("http://localhost:5000/login", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        email: "test@gmail.com",
        password: "123456"
    })
})
.then(res => res.json())
.then(data => {
    localStorage.setItem("token", data.token);
});

⏳ Step 11: Token Expiry Handling

We set token expiration time to improve security.


jwt.sign({ id: user._id }, "secretKey", { expiresIn: "1h" });

After 1 hour, the user must login again.


🚪 Step 12: Logout System


function logout() {
    localStorage.removeItem("token");
    window.location.href = "/login.html";
}

🌍 Real-World Applications

  • E-commerce websites
  • Admin dashboards
  • Online learning platforms
  • SaaS applications
  • Banking systems

⚠️ Common Mistakes

  • Storing passwords without hashing
  • Not using HTTPS
  • Hardcoding secret keys
  • Not validating user input

❓ FAQs

1. What is JWT?

JWT is a token-based authentication system used to securely transmit user data.

2. Why use bcrypt?

Bcrypt is used to securely hash passwords before storing them in the database.

3. Is this system production-ready?

Yes, but you should add advanced security features for production use.

4. Can I use SQL instead of MongoDB?

Yes, you can use MySQL or PostgreSQL as alternatives.

5. What is middleware?

Middleware is a function that runs before accessing protected routes.


🎯 Conclusion

In this tutorial, you learned how to build a complete full-stack authentication system using Node.js, Express, MongoDB, and JWT.

This project is a strong foundation for real-world web development and backend engineering.

Keep practicing and integrate this system into larger applications to improve your skills.


Prasun Barua is an Electrical and Electronic Engineer, engineering consultant, and technical author. He writes instructional and reference books covering electrical engineering, renewable energy, semiconductors and microelectronics, software, and industrial automation. His books include Semiconductor Device Fabrication Process, How to Design and Size Solar PV Systems, Fundamentals of Electrical Substations, and PLC Industrial Automation. His other titles cover electronics fundamentals, MOSFETs, VLSI design, switchgear, Python programming, MATLAB, industrial AI, and computer networking. Written for engineering students, technicians, practicing engineers, and technology enthusiasts, his books focus on clear technical explanations, practical calculations, examples, and step-by-step approaches to engineering problems.