AluminicompSRESCoeKo
20 views
18 slides
Nov 02, 2025
Slide 1 of 18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
About This Presentation
My Youtube Channel:-
https://www.youtube.com/channel/UCTSeqoJEf28oJB7cqfkq7ZQ
This presentation explains how to implement secure user authentication in a Node.js and Express backend using JSON Web Tokens (JWT) and MongoDB as the database.
It covers the complete authentication workflow, from user r...
My Youtube Channel:-
https://www.youtube.com/channel/UCTSeqoJEf28oJB7cqfkq7ZQ
This presentation explains how to implement secure user authentication in a Node.js and Express backend using JSON Web Tokens (JWT) and MongoDB as the database.
It covers the complete authentication workflow, from user registration and password hashing to token generation and route protection.
Key topics include:
Understanding Authentication vs Authorization
What is JWT and how it works (Header, Payload, Signature)
Environment setup using dotenv, mongoose, and bcryptjs
Creating Register and Login APIs with password hashing
Generating and verifying JWT tokens
Protecting routes using middleware
Secure storage of tokens (HTTP-only cookies, headers)
Real-world best practices for securing APIs
This presentation is ideal for:
Students learning the MERN Stack
Developers exploring API Security and Token-based Authentication
Anyone preparing for backend development interviews or academic presentations
By the end of this presentation, viewers will understand how to build a secure authentication system for modern web applications using Node.js, Express, MongoDB, and JWT.
Size: 874.83 KB
Language: en
Added: Nov 02, 2025
Slides: 18 pages
Slide Content
Implementing Server-Side
Authentication with JWT in Node.js
and Express
•Prepared By:-
–J. N. Kale
–Assistant Professor,
–Computer Engineering Department,
–Sanjivani College of Engineering, Kopargaon
–Youtube Channel
Prepared By: Kale Jaydeep N.
What is Authenticationand
Authorization?
-Authentication:Verifywhotheuseris("Who
areyou?“)
-Authorization:Verifywhattheycanaccess.
Decideswhattheauthenticateduseris
allowedtodo(e.g.,admincandelete,usercan
onlyview).
-WewilluseJWTmainlyforauthentication,and
itcanalsocarryauthorizationclaims.
Prepared By: Kale Jaydeep N.
What is JWT?
•A compact, token used to securely transmit
information between client and server.
•Proves identity after login (authentication)
•Can carry user roles/permissions (authorization)
•JWTas a way to securely send user info between
client and server.
•JWT consists of 3 parts, separated by dots:
•Header→ algorithm & token type
•Payload→ user data (claims, e.g., id, email, role)
•Signature→ verification using secret key
xxxxx.yyyyy.zzzzz
Prepared By: Kale Jaydeep N.
Header
•The Headeris the first part of a JWT.
It tells the server how the token was generated and how it
should be verified.
•It’s a small JSON object, usually containing:
•alg→ Algorithm used to sign the token
–e.g., "HS256" (HMAC + SHA-256), "RS256" (RSA with SHA-256)
–This tells the server how to verify the signature.
•typ→ Type of token
–Always "JWT" for JSON Web Token.
{
"alg": "HS256",
"typ": "JWT"
}
Prepared By: Kale Jaydeep N.
JWT Payload
•The Payloadis the second partof a JWT.
It contains claims—pieces of information about the
user or token.
•Contains the user identity(id, email).
•Stores authorization info(role, permissions).
•Provides token validity(exp, iat).
{
"id": "12345",
"email": "[email protected]",
"role": "admin",
"iat": 1696425600,
"exp": 1696429200
}
Prepared By: Kale Jaydeep N.
JWT Signature
•The Signatureis the part of a JWT that ensures the token’s
integrity and authenticity. It guarantees that:
•The token was created by a trusted source(authenticity)
•The token has not been altered(integrity)
•Without the signature, anyone could modify the payload
(like user roles, IDs) and the server wouldn’t be able to
detect it.
•The signature is generated using three pieces of data:
–Header(Base64Url encoded)
–Payload(Base64Url encoded)
–Secret Key(or private key for asymmetric algorithms)
•Steps in simple terms:
–Encode the headerand payloadto Base64Url.
–Concatenate them with a dot: header.payload.
–Apply a cryptographic algorithmwith a secret/private key.
–The resulting hash is the signature.
Prepared By: Kale Jaydeep N.
Flow
A. Authentication
1.Client sends credentials to the authentication
endpoint (e.g., POST /login with username/password)
over HTTPS.
2.Server verifies credentials against DB.
3.If valid, server builds claims (payload) —
–e.g., { sub: "123", role: "user", iat: 1690000000, exp:
1690003600 }.
4.Server creates header + payload, signs them using
chosen algorithm and secret/private key → produces
JWT.
5.Server returns JWT to client (in response body or set
as cookie).
Prepared By: Kale Jaydeep N.
•B. Client stores the JWT (important security
decision)
–Options:
•HTTP-only secure cookie(recommended for web apps
to avoid XSS reading).
•localStorage/ sessionStorage(easy but vulnerable to
XSS —generally not recommended for access tokens).
•In-memory(best against XSS but lost on reload).
Prepared By: Kale Jaydeep N.
•C. Authenticated requests (Client → Server)
–Client attaches JWT to requests:
•Common: Authorization: Bearer <JWT>
•Or browser cookie automatically sent if token in cookie.
–Server receives request and extracts token.
Prepared By: Kale Jaydeep N.
Verification Process
•When a server receives a JWT:
–It takes the header and payload.
–Using its secret key, it recalculates the signature.
–Compares it with the signature in the token.
–If they match → token is valid.
If they don’t match → token is invalid or
tampered.
Prepared By: Kale Jaydeep N.
npminstall express mongoose
jsonwebtokenbcryptjsdotenvcors
•dotenv
•A library to load environment variables from a .env file
into process.env.
•Why used: Keeps secrets (like DB connection strings,
JWT secret keys, API keys) outside your code.
•Without it: You might hardcode sensitive data inside
your code, which is unsafe.
Prepared By: Kale Jaydeep N.
.envfile
•PORT=5000
•MONGO_URI=mongodb://localhost:27017/jw
tdemo
•JWT_SECRET=supersecretkey
•JWT_EXPIRE=1h
Prepared By: Kale Jaydeep N.
// Importing required modules
const express = require("express"); // Express framework for building web applications and APIs
const mongoose = require("mongoose"); // Mongoose library for connecting and interacting with
MongoDB
const bcrypt= require("bcryptjs"); // bcryptjsfor hashing passwords securely
const jwt= require("jsonwebtoken"); // jsonwebtokenfor generating and verifying JWT tokens
const dotenv= require("dotenv"); // dotenvto load environment variables from a .env file
// Load environment variables (like DB URI, secret keys) from .env file into process.env
dotenv.config();
// Create an Express application instance
const app = express();
// Middleware to parse incoming JSON request bodies (e.g., from POST or PUT requests)
app.use(express.json());
// ---------------------------
// MongoDB Connection Section
// ---------------------------
// Connect to MongoDB using Mongoose
// The connection string (MONGO_URI) is stored in the .env file for security
mongoose.connect(process.env.MONGO_URI)
.then(() => console.log("MongoDB Connected")) // On successful connection
.catch(err => console.log(err)); // On connection error, print the error message
Prepared By: Kale Jaydeep N.
// --------------------------------------
// User Schema and Model Definition
// --------------------------------------
// Define a new Mongoose Schema for the "User" collection
// A schema acts like a blueprint for how user data will be stored in MongoDB
const userSchema= new mongoose.Schema({
// 'username' field: must be a string, required for every user, and must be unique (no
duplicate usernames allowed)
username: { type: String, required: true, unique: true },
// 'password' field: must be a string and is required
// The password will be stored as a hashed value using bcrypt(not plain text)
password: { type: String, required: true }
});
// Create a Mongoose model named "User" based on the schema above
// This model provides methods to interact with the "users" collection in MongoDB
(e.g., find, create, update, delete)
const User = mongoose.model("User", userSchema);
Prepared By: Kale Jaydeep N.
// --------------------------------------
// POST /register → Register New User
// --------------------------------------
app.post("/register", async (req, res) => {
try {
// Extract 'username' and 'password' from the request
body (sent by client)
const { username, password } = req.body;
// Check if a user with the same username already
exists in the database
const existingUser= await User.findOne({ username
});
// If the username is already taken, return an error
response (HTTP 400 = Bad Request)
if (existingUser) return res.status(400).json({ message:
"User already exists" });
// Hash the plain-text password using bcryptfor
secure storage
// The second argument (10) is the salt rounds —
higher means more secure but slower
const hashed = await bcrypt.hash(password, 10);
const hashed = await bcrypt.hash(password, 10);
// Create a new User document with the
provided username and the hashed password
const user = new User({ username, password:
hashed });
// Save the new user record into the MongoDB
database
await user.save();
// Send a success response to the client
res.json({ message: "User registered
successfully" });
} catch (err) {
// If any error occurs (e.g., DB error, validation
issue), return a server error (HTTP 500)
res.status(500).json({ error: err.message});
}
});
Prepared By: Kale Jaydeep N.
// --------------------------------------
// POST /login → Authenticate User & Generate
JWT
// --------------------------------------
app.post("/login", async (req, res) => {
try {
// Extract 'username' and 'password' from the
request body (sent by client)
const { username, password } = req.body;
// Step 1: Check if a user with the given username
exists in the database
const user = await User.findOne({ username });
// If no user is found, return an error response
if (!user) return res.status(400).json({ message:
"Invalid credentials" });
// Step 2: Compare the entered password with the
hashed password stored in the database
// bcrypt.compare() returns true if both passwords
match
const isMatch= await bcrypt.compare(password,
user.password);
if (!isMatch) return res.status(400).json({ message:
"Invalid credentials" });
// Step 3: If credentials are valid, generate a JWT
(JSON Web Token)
// The token payload contains user ID and
username for identification
// The secret key and expiry time are taken from
environment variables (.env)
const token = jwt.sign(
{ id: user._id, username: user.username}, //
Payload
process.env.JWT_SECRET, // Secret
key for signing
{ expiresIn: process.env.JWT_EXPIRE} //
Token expiration time (e.g., "1h" = 1 hour)
);
// Step 4: Send a success response with the
generated token
// The client will store this token and include it
in future requests to access protected routes
res.json({ message: "Login successful", token });
} catch (err) {
// Step 5: Handle any unexpected errors
(database issues, server crash, etc.)
res.status(500).json({ error: err.message});
}
});
Prepared By: Kale Jaydeep N.
// --------------------------------------
// Middleware: verifyToken()
// Purpose: To protect routes by verifying JWT tokens
// --------------------------------------
function verifyToken(req, res, next) {
// Step 1: Retrieve the 'Authorization' header from the
incoming request
// The format should be: Authorization: Bearer
<token>
const authHeader= req.headers["authorization"];
// Step 2: Extract the token part (the string after
'Bearer ')
// If no header is present, 'token' will be undefined
const token = authHeader&& authHeader.split(" ")[1];
// e.g., "Bearer abc.def.ghi" → "abc.def.ghi"
// Step 3: If no token is provided, deny access with
status 401 (Unauthorized)
if (!token) return res.status(401).json({ message: "No
token provided" });
// Step 4: Verify the token using the secret key
stored in the environment variable
// jwt.verify() checks the token's signature and
expiration
jwt.verify(token, process.env.JWT_SECRET, (err,
decoded) => {
// If verification fails (invalid or expired token),
return 403 (Forbidden)
if (err) return res.status(403).json({ message:
"Invalid token" });
// Step 5: If token is valid, 'decoded' contains the
payload (e.g., user ID, username)
// Attach the decoded data to the request object
so it can be used in the next middleware or
route
req.user= decoded;
// Step 6: Continue to the next middleware or the
protected route handler
next();
});
}
Prepared By: Kale Jaydeep N.
// --------------------------------------
// Protected Route Example
// --------------------------------------
// Define a protected GET route that can only be accessed if the user has a valid JWT
// The 'verifyToken' middleware runs first —if it passes, this route executes
app.get("/protected", verifyToken, (req, res) => {
// The middleware added 'req.user' (decoded token info) earlier
// So we can use 'req.user.username' to personalize the response
res.json({
message: `Welcome ${req.user.username}! This is a protected route.`,
});
});
// --------------------------------------
// Start the Express Server
// --------------------------------------
// Define which port the server will listen on
// Use the PORT value from the .env file if available, otherwise default to 5000
const PORT = process.env.PORT|| 5000;
// Start the Express server and begin listening for incoming requests
// Once running, a message will be logged in the console
app.listen(PORT, () =>
console.log(`??????Server running on port ${PORT}`)
);
Prepared By: Kale Jaydeep N.