π Create a Basic JWT Authentication System Using Express.js: A Step-by-Step Guide


Are you learning backend development and want to understand how authentication really works?
This guide walks you through creating a simple user authentication system using Node.js, Express.js, and JWT (JSON Web Tokens). π₯
π§ What You'll Learn
β
How to set up a simple Express.js server
β
Create a basic Signup and Signin flow
β
Generate and validate JWT tokens
β
Protect routes using tokens (middleware-style logic)
β
Understand how authentication works at a basic level
π οΈ Tech Stack
Node.js
Express.js
jsonwebtoken (JWT for creating and verifying tokens)
Plain in-memory data (no database)
π§ Project Overview
We built a basic Express.js server that allows:
π Signup β Register a user with username and password
π Signin β Authenticate user and return a JWT token
π /me Route β A protected route to fetch user info from the token
All user data is stored in memory for simplicity. In production, this would be in a secure database.
Code :
const express = require('express');
const jwt = require('jsonwebtoken');
const JWT_SECRET = "random";
const app = express();
app.use(express.json());
let users = [];
app.post("/signup", function(req, res){
const username = req.body.username;
const password = req.body.password;
if(!username || !password){
return res.status(400).send("Username and password are required");
}
const existingUser = users.find(user => user.username === username);
if (existingUser) {
return res.status(400).send("User already signed up");
}
users.push({
username : username,
password : password
});
res.send("User signed up successfully");
});
app.post("/signin", function(req, res){
const { username, password } = req.body;
const foundUser = users.find(user =>
user.username === username && user.password === password
);
if(foundUser){
const token = jwt.sign({ username }, JWT_SECRET);
res.json({ token });
} else {
res.status(400).send("Invalid Credentials..");
}
});
app.get("/me", function(req, res){
const token = req.headers.authorization;
const decodedInfo = jwt.verify(token, JWT_SECRET);
const username = decodedInfo.username;
const user = users.find(user => user.username === username);
if(user){
res.send({
username: user.username,
password: user.password
});
} else {
res.status(401).send({ error: "Unauthorized" });
}
});
app.listen(3000);
ποΈ Route Breakdown
π’ POST /signup
Accepts username and password
Checks if user already exists
Adds user to in-memory array
POST /signup
Body: { "username": "john", "password": "doe123" }
π’ POST /signin
Verifies if the credentials match
If valid, generates a JWT token
POST /signin
Body: { "username": "john", "password": "doe123" }
Response:
{ "token": "eyJhbGciOi..." }
π§ͺ Testing Your App
You can use tools like Postman, Thunder Client, or curl to test each route.
Make sure you:
Signup first
Signin and copy the token
Use that token in the
/me
route
π Whatβs Next?
This was a basic beginner-friendly implementation. To improve further:
β
Hash passwords using bcrypt
β
Store users in a real database (MongoDB, PostgreSQL, etc.)
β
Add token expiration and refresh tokens
β
Add role-based access (admin, user, etc.)
π Source Code
You can check out the full code here :
Subscribe to my newsletter
Read articles from Skanda Prasad D directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
