dev-resources.site
for different kinds of informations.
JWT Authentication With NodeJS
Published at
1/10/2025
Categories
node
authentication
jwt
Author
pedrotech
Author
9 person written this
pedrotech
open
Create a Custom Authentication System with Node.js and JWT
Authentication is essential for modern web applications. In this tutorial, we’ll build a custom authentication system using Node.js, JWT, and React. You'll learn how to set up secure user registration and login, manage authentication states, and handle token expiration with refresh tokens.
Prerequisites
Before starting, ensure you have:
- Node.js installed on your system.
- Basic understanding of React, Node.js, and JavaScript.
- A code editor like VS Code.
Step 1: Set Up the Backend
Start by creating the backend for handling user authentication.
1.1 Initialize the Project
mkdir node-jwt-auth
cd node-jwt-auth
npm init -y
1.2 Install Required Libraries
npm install express jsonwebtoken bcrypt cors
Step 2: Implement the Backend
2.1 Create the Server
Create a file named server.js
in the project root:
const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const cors = require("cors");
const app = express();
app.use(express.json()); // Built-in middleware to parse JSON requests
app.use(cors());
// Mock user database
const users = [];
// JWT secret keys
const ACCESS_TOKEN_SECRET = "your_access_token_secret";
const REFRESH_TOKEN_SECRET = "your_refresh_token_secret";
// Refresh token storage
let refreshTokens = [];
// User registration endpoint
app.post("/register", async (req, res) => {
const { username, password } = req.body;
// Check if user already exists
if (users.find((user) => user.username === username)) {
return res.status(400).json({ error: "User already exists" });
}
// Hash the password
const hashedPassword = await bcrypt.hash(password, 10);
// Save user
users.push({ username, password: hashedPassword });
res.status(201).json({ message: "User registered successfully" });
});
// User login endpoint
app.post("/login", async (req, res) => {
const { username, password } = req.body;
// Find user
const user = users.find((user) => user.username === username);
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(400).json({ error: "Invalid username or password" });
}
// Generate tokens
const accessToken = jwt.sign({ username }, ACCESS_TOKEN_SECRET, {
expiresIn: "15m",
});
const refreshToken = jwt.sign({ username }, REFRESH_TOKEN_SECRET);
refreshTokens.push(refreshToken); // Store refresh token
res.json({ accessToken, refreshToken });
});
// Refresh token endpoint
app.post("/token", (req, res) => {
const { token } = req.body;
if (!token || !refreshTokens.includes(token)) {
return res.status(403).json({ error: "Invalid refresh token" });
}
try {
const user = jwt.verify(token, REFRESH_TOKEN_SECRET);
const accessToken = jwt.sign(
{ username: user.username },
ACCESS_TOKEN_SECRET,
{
expiresIn: "15m",
}
);
res.json({ accessToken });
} catch {
res.status(403).json({ error: "Invalid token" });
}
});
// Logout endpoint
app.post("/logout", (req, res) => {
const { token } = req.body;
refreshTokens = refreshTokens.filter((t) => t !== token);
res.status(200).json({ message: "Logged out successfully" });
});
// Protected route
app.get("/protected", (req, res) => {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(" ")[1];
if (!token) return res.status(401).json({ error: "Unauthorized" });
try {
const decoded = jwt.verify(token, ACCESS_TOKEN_SECRET);
res.json({ message: "Welcome to the protected route!", user: decoded });
} catch {
res.status(403).json({ error: "Invalid or expired token" });
}
});
// Start the server
app.listen(3001, () => {
console.log("Server running on http://localhost:3001");
});
Step 3: Set Up the Frontend
3.1 Initialize the React App
npx create-react-app client
cd client
npm install axios
Step 4: Create React Components
4.1 Create an AuthContext
Inside the src
folder, create a new file AuthContext.js
:
import React, { createContext, useState, useContext } from "react";
import axios from "axios";
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = async (username, password) => {
try {
const { data } = await axios.post("http://localhost:3001/login", {
username,
password,
});
localStorage.setItem("accessToken", data.accessToken);
localStorage.setItem("refreshToken", data.refreshToken);
setUser({ username });
} catch (err) {
console.error(err);
alert("Invalid credentials");
}
};
const logout = async () => {
const refreshToken = localStorage.getItem("refreshToken");
await axios.post("http://localhost:3001/logout", { token: refreshToken });
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
4.2 Create Login and Protected Components
Login Component
import React, { useState } from "react";
import { useAuth } from "./AuthContext";
const Login = () => {
const { login } = useAuth();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
return (
<div>
<h1>Login</h1>
<input
type="text"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={() => login(username, password)}>Login</button>
</div>
);
};
export default Login;
Protected Component
import React, { useEffect, useState } from "react";
import axios from "axios";
const Protected = () => {
const [message, setMessage] = useState("");
useEffect(() => {
const fetchData = async () => {
try {
const token = localStorage.getItem("accessToken");
const { data } = await axios.get("http://localhost:3001/protected", {
headers: { Authorization: `Bearer ${token}` },
});
setMessage(data.message);
} catch {
setMessage("Unauthorized");
}
};
fetchData();
}, []);
return <div>{message}</div>;
};
export default Protected;
Step 5: Run the Application
- Start the backend server:
node server.js
- Start the React frontend:
npm start
Final Thoughts
Congratulations! You've built a secure authentication system with Node.js, JWT, and React. For more tutorials, visit my YouTube Channel.
node Article's
30 articles in total
Breaking the Scale Barrier: 1 Million Messages with NodeJS and Kafka
read article
assert in Nodejs and its usage in Grida source code
read article
Understanding Node.js Cluster: The Core Concepts
read article
🌟 A New Adventure Begins! 🛵🍕
read article
How “Silicon Valley” Inspired Me to Create a Photo Compressor CLI for Web Developers
read article
How Does This Jewelry Customization Site Work? Need Insights!
read article
Building a Secure Authentication API with TypeScript, Node.js, and MongoDB
read article
Understanding OAuth 1.0a Signature Generation: Postman vs. Node.js Library and Custom Implementation
read article
How to Fix the “Record to Delete Does Not Exist” Error in Prisma
read article
[Boost]
read article
Run NextJS App in shared-hosting cPanel domain!
read article
Construindo uma API segura e eficiente com @fastify/jwt e @fastify/mongodb
read article
New ways to engage with the stdlib community!
read article
Sore Throat: Causes, Symptoms, and Treatment
read article
Back to MonDEV 2025
read article
🌟 How to Fix Node.js Path Issues in VS Code (Step-by-Step Guide)
read article
How to write unit tests and E2E tests for NestJS applications
read article
Cookies auto clearing after browser refresh issue , CORS related express cookies issue
read article
Exploring TypeScript Support in Node.js v23.6.0
read article
Mastering Backend Node.js Folder Structure, A Beginner’s Guide
read article
how to setup express api from scratch
read article
Load Balancing Node.js Applications with Nginx Upstream Configuration
read article
Using LRU Cache in Node.js and TypeScript
read article
Welcome to Siitecch! Your Go-To Platform for Beginner-Friendly Full-Stack JavaScript Learning.
read article
I Really like Middleware in NodeJs/Express.
read article
Your own Telegram bot on NodeJS with TypeScript, Telegraf and Fastify (Part 3)
read article
Understanding Node.js Cluster: The Core Concepts
read article
JWT Authentication With NodeJS
currently reading
Stream de Arquivo PDF ou Imagem S3 - AWS
read article
Understanding Node.js Alpine Versions: A Lightweight Choice for Your Projects
read article
Featured ones: