How to Build Token-Based Authentication in Node.js with JWT & MySQL (With Code)?

By Atit Purani

June 11, 2025

When it comes to building secure APIs and modern web apps, Node.js JWT authentication stands out as a fast, scalable, and developer-friendly solution.

Nowadays users expect instant access and businesses need robust ways to verify identity, protect data, and secure routes without slowing down performance.

That’s where JSON Web Tokens (JWT) come in.

Paired with Node.js, JWT makes it easy to create stateless authentication systems that are perfect for login systems, admin panels, mobile apps, and RESTful APIs.

Whether you’re building a SaaS platform or a secure internal tool, learning token-based authentication in Node.js can help you build safer, faster apps.

Here you can find a step-by-step guide to build token-based authentication in Node.Js by using JWT & MySQL.

What Is Token-Based Authentication?

Token-based authentication in Node.js is a method where users receive a token, usually a JWT, after logging in.

This token is then sent along with each request to verify their identity, without needing to store session data on the server.

JWT vs. Session-based Authentication:

  • Session-based stores user info in memory or databases, harder to scale.
  • JWT-based sends the token with every request, easier to scale and integrate across services.

Benefits of Token-Based Authentication:

benefits-of-token-based-authentication

  • Stateless : No session storage is required.
  • Scalable : Great for APIs, mobile, and distributed systems.
  • Secure : Encrypted tokens with expiration times.
  • Cross-platform : Works with frontend frameworks and mobile apps.

This is why Node.js with JWT is now the go-to solution for authentication in modern applications.

Why Use JWT for Node.js Authentication with MySQL?

So, why combine JWT authentication in Node.js with MySQL database?

Let’s explore it.

JWT’s Role in Security

JWT tokens contain all the important user information (like ID or email) in an encrypted format.

After a successful login, the server generates this token and returns it to the client.

Every future request includes this token for quick identity verification without needing to re-check the database each time.

Why Does MySQL Work Well Here?

MySQL is reliable, fast, and widely supported. It’s perfect for storing and querying user credentials securely especially when combined with hashing libraries like bcrypt.

Here’s a sample structure of the Users table in MySQL:

      
       CREATE TABLE users (
          id INT AUTO_INCREMENT PRIMARY KEY,
          name VARCHAR(255) NOT NULL,
          email VARCHAR(255) UNIQUE NOT NULL,
          password VARCHAR(255) NOT NULL,
          created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        );
        
    

Copied!

This setup allows us to safely store and manage user accounts while using JWT to handle real-time authentication securely.

Project Setup: Tools, Dependencies, and Directory Structure

Before we learn about building our JWT login system in Node.js, let’s set up the tools and dependencies you’ll need.

Required Tools:

  • Node.js : Our backend runtime environment.
  • Express.js : To simplify server setup.
  • MySQL : Relational database to store user credentials.
  • Postman : For testing the API.

Install the Required Packages

Open your terminal and run:

        
          npm init -y
          npm install express mysql2 jsonwebtoken bcrypt dotenv
        
      

Copied!

Optional (for dev):

        
          npm install --save-dev nodemon
        
    

Copied!

Suggested Directory Structure:

jwt-auth-nodejs/
├── controllers/
│ └── authController.js
├── middleware/
│ └── authMiddleware.js
├── routes/
│ └── authRoutes.js
├── .env
├── db.js
├── server.js
└── package.json

Learn to integrate Razorpay payment gateway in your Node.Js app.

How to Build the API: Step-by-Step Guide (With Code)?

Let’s go through a step-by-step Node.js JWT & MySQL authentication tutorial that shows you how to build a secure login system.

Create Express Server (server.js)

        
          const express = require('express');
          const authRoutes = require('./routes/authRoutes');
          require('dotenv').config();
          
          const app = express();
          app.use(express.json());
          
          app.use('/api/auth', authRoutes);
          
          const PORT = process.env.PORT || 5000;
          app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
          
      

Copied!

Connect to MySQL (db.js)

          
            const mysql = require('mysql2');
 
            const db = mysql.createConnection({
              host: 'localhost',
              user: 'root',
              password: 'your_mysql_password',
              database: 'jwt_demo'
            });
            
            db.connect((err) => {
              if (err) throw err;
              console.log('Connected to MySQL DB');
            });
            
            module.exports = db;
            
        

Copied!

Create Signup Route (authController.js)

          
              const db = require('../db');
              const bcrypt = require('bcrypt');
              const jwt = require('jsonwebtoken');
              
              exports.signup = async (req, res) => {
                const { name, email, password } = req.body;
                const hashedPassword = await bcrypt.hash(password, 10);
              
                db.query(
                'INSERT INTO users (name, email, password) VALUES (?, ?, ?)',
                [name, email, hashedPassword],
                (err, result) => {
                  if (err) return res.status(500).json({ error: err.message });
                  res.status(201).json({ message: 'User registered successfully!' });
                }
                );
              };
            
        

Copied!

Create Login Route (authController.js)

          
              exports.login = (req, res) => {
                const { email, password } = req.body;
              
                db.query('SELECT * FROM users WHERE email = ?', [email], async (err, results) => {
                if (err || results.length === 0) return res.status(401).json({ error: 'User not found' });
              
                const user = results[0];
                const isMatch = await bcrypt.compare(password, user.password);
              
                if (!isMatch) return res.status(401).json({ error: 'Invalid credentials' });
              
                const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '1h' });
              
                res.status(200).json({ message: 'Login successful', token });
                });
              };
            
        

Copied!

Protect Routes with JWT Middleware (authMiddleware.js)

          
            const jwt = require('jsonwebtoken');
 
              module.exports = (req, res, next) => {
                const authHeader = req.headers['authorization'];
                const token = authHeader?.split(' ')[1];
              
                if (!token) return res.status(403).json({ error: 'Token missing' });
              
                jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
                if (err) return res.status(401).json({ error: 'Invalid token' });
                req.user = user;
                next();
                });
              };
            
        

Copied!

Use it in any route like this:

        
        const authMiddleware = require('../middleware/authMiddleware');
  
          router.get('/protected', authMiddleware, (req, res) => {
            res.json({ message: 'This is a protected route', user: req.user });
          });
        
      

Copied!

Explore Node Express JWT auth demo with detailed code.

How to Test the Token-Based Login System in Postman?

Let’s test our Node.js secure login using JWT and MySQL in Postman:

Steps:

1. Signup

  • POST /api/auth/signup
        
          Body:
          {
            "name": "Alice",
            "email": "alice@example.com",
            "password": "securepass123"
          }
        
      

Copied!

2. Login

  • POST /api/auth/login
        
          Body:
          {
            "email": "alice@example.com",
            "password": "securepass123"
          }
        
      

Copied!

        
            Response:
            {
              "message": "Login successful",
              "token": "your_jwt_token"
            } 
        
      

Copied!

3. Access Protected Route

  • GET /api/auth/protected
        
            Add Header:
            Authorization: Bearer your_jwt_token
        
      

Copied!

What Are the Common JWT Authentication Mistakes to Avoid?

JWT-authentication-mistakes-to-avoid

Even though JWT and Node.js authentication is powerful, there are some mistakes that can put your app at risk. Let’s highlight the common ones:

1. Not Setting Token Expiration

  • Tokens should expire after a short time (e.g., 15–30 minutes).
  • Long-lived tokens can be hijacked and misused.

2. Storing Tokens Insecurely

  • Never store JWTs in plain-text. Avoid localStorage if possible use HttpOnly cookies to prevent XSS attacks.

3. Skipping HTTPS

  • Always use HTTPS to encrypt the data in transit.
  • Without it, attackers can steal tokens via man-in-the-middle attacks.

4. Missing Input Validations

  • Don’t trust any data blindly.
  • Always validate user inputs during signup/login to avoid injection attacks and broken auth flows.

Following best practices will help your Node.js authentication with MySQL setup stay secure and reliable.

How Seven Square Can Help to Build Secure Authentication Systems?

At Seven Square, we specialize in building robust, scalable authentication systems that power modern web applications.

With years of experience in Node.js development and security implementation, our team has helped
numerous businesses create secure & user-friendly authentication solutions.

  • End-to-End Security Implementation : We specialize in implementing complete authentication systems using industry-standard practices like JWT tokens, secure password hashing, and multi-factor authentication.
  • Scalable Database Architecture : Our developers design and optimize database schemas for authentication systems that can handle high-traffic applications while maintaining security.
  • Custom Authentication Solutions : We build flexible systems that can easily adapt to changing security requirements and integrate smoothly with your existing technology stack.
  • Performance-Optimized Solutions : We implement authentication systems with caching strategies, token refresh mechanisms, and optimized middleware that minimize latency while maximizing security.

Want to get a customized NodeJs app with JWT? Contact Us Now!

How to Store JWT Tokens on Frontend (Best Practices)?

After generating a token, the next big question is: where should you store it on the frontend?

Cookies vs LocalStorage:

  • HttpOnly Cookies (Best) : Can’t be accessed by JavaScript, safe from XSS.
  • LocalStorage (Riskier) : Easily accessible by malicious scripts; avoid for long-lived tokens.

Use Refresh Tokens

  • To keep the user logged in without compromising security, use short-lived access tokens and rotate them with refresh tokens.

Connecting with Frontend Frameworks

  • If you’re building with React, Vue, or Angular, set up an auth context or state management system to handle JWTs properly.
  • You can store tokens in memory or use cookies depending on your security requirements.

FAQs

  • JWT (JSON Web Token) is a compact, self-contained token format used in Node.js to securely transmit user information between the client and server.
  • It’s commonly used in token-based authentication systems to verify identity without using server-side sessions.

  • JWTs are stateless, meaning they don’t require server memory to track user sessions.
  • This makes them scalable, fast, and ideal for modern APIs, SPAs, and mobile apps built with Node.js.

  • Store access tokens in HttpOnly cookies or secure local storage, use HTTPS, set short expiration times, and validate tokens on each request using middleware.

  • Yes, you can use MySQL to store user credentials (like email and hashed passwords) and Node.js with JWT to handle authentication securely.
  • This combination is reliable for real-world applications.

Get in Touch

Got a project idea? Let's discuss it over a cup of coffee.

    Get in Touch

    Got a project idea? Let's discuss it over a cup of coffee.

      COLLABORATION

      Got a project? Let’s talk.

      We’re a team of creative tech-enthus who are always ready to help business to unlock their digital potential. Contact us for more information.