JWT (JSON Web Token) authentication is a widely-used approach for securing web applications. It enables secure communication and identity verification, making it ideal for APIs. In this article, weβll implement JWT authentication in a Node.js app using MongoDB for data storage.
Let's jump right in! π
π Table of Contents
- What is JWT Authentication?
- π± Setting Up the Project
- π οΈ Connecting to MongoDB
- π Environment Configuration with .env File
- βοΈ Setting Up the Express App
- π€ Creating the User Model
- π Building Authentication Routes
- π‘οΈ Securing Routes with Middleware
- π Testing the API
What is JWT Authentication?
JWT authentication uses JSON Web Tokens to verify user identity within a web app. A JWT consists of three parts:
- Header: Contains the token type and encryption method.
- Payload: Stores user-specific information, such as username and role.
- Signature: Verifies the token's validity, ensuring data integrity.
The token is presented by users to access resources, acting as proof of their identity.
Step 1: π± Setting Up the Project
To get started, create a new directory and initialize the project:
mkdir nodejs-jwt-auth
cd nodejs-jwt-auth
npm init -y
Install the required dependencies:
npm install express mongoose jsonwebtoken dotenv
- express: Framework for building web servers.
- mongoose: MongoDB library for handling data models.
- jsonwebtoken: Library for generating and verifying JWTs.
- dotenv: Manages environment variables securely.
Step 2: π οΈ Connecting to MongoDB
Use MongoDB Atlas for cloud storage. Sign in to MongoDB Atlas and obtain your connection string.
In your .env
file:
MONGODB_URL='mongodb+srv://your-username:your-password@cluster.mongodb.net/your-database'
SECRET_KEY='your_secret_key'
Replace the placeholders with your credentials.
Step 3: π Environment Configuration with .env File
Create a .env
file to store your MongoDB URL and secret key for JWTs.
In .env
:
MONGODB_URL='your-mongodb-connection-string'
SECRET_KEY='your-secret-key'
Step 4: βοΈ Setting Up the Express App
Create index.js
to configure Express and MongoDB connections:
const express = require("express");
const mongoose = require("mongoose");
require("dotenv").config();
const app = express();
const port = 3000;
app.use(express.json());
mongoose.connect(process.env.MONGODB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log("MongoDB connected"))
.catch(error => console.error("Connection error", error));
app.listen(port, () => console.log(`Server running on port ${port}`));
Run the app:
node index.js
For automatic restarts, install nodemon:
npm install -g nodemon
nodemon index.js
Step 5: π€ Creating the User Model
Define a User
schema in models/User.js
:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
module.exports = mongoose.model("User", userSchema);
Step 6: π Building Authentication Routes
In routes/auth.js
, define signup and login routes for creating users and generating JWT tokens.
const express = require("express");
const jwt = require("jsonwebtoken");
const User = require("../models/User");
const router = express.Router();
router.post("/signup", async (req, res) => {
try {
const { username, password } = req.body;
const user = new User({ username, password });
await user.save();
res.status(201).json({ message: "User registered successfully" });
} catch (error) {
res.status(500).json({ message: "Internal Server Error" });
}
});
router.post("/login", async (req, res) => {
const { username, password } = req.body;
try {
const user = await User.findOne({ username });
if (!user || user.password !== password) {
return res.status(401).json({ message: "Invalid credentials" });
}
const token = jwt.sign({ id: user._id, username: user.username }, process.env.SECRET_KEY);
res.json({ token });
} catch (error) {
res.status(500).json({ message: "Internal Server Error" });
}
});
module.exports = router;
Step 7: π‘οΈ Securing Routes with Middleware
Create a middleware.js
file to verify JWTs:
const jwt = require("jsonwebtoken");
function verifyJWT(req, res, next) {
const token = req.headers["authorization"];
if (!token) {
return res.status(401).json({ message: "Access denied" });
}
jwt.verify(token, process.env.SECRET_KEY, (err, user) => {
if (err) {
return res.status(403).json({ message: "Invalid token" });
}
req.user = user;
next();
});
}
module.exports = verifyJWT;
Step 8: π Testing the API
-
Signup: POST to
/auth/signup
with a JSON body:
{ "username": "john_doe", "password": "securepass" }
-
Login: POST to
/auth/login
with the same credentials:
{ "username": "john_doe", "password": "securepass" }
Accessing Protected Route: Send a GET request to
/protected
with the JWT token in theAuthorization
header.
Congratulations! Youβve now successfully implemented JWT authentication in a Node.js app. This setup secures your API routes, allowing only authenticated users to access them.
That's all for today.
And also, share your favourite web dev resources to help the beginners here!
Connect with me:@ LinkedIn and checkout my Portfolio.
Explore my YouTube Channel! If you find it useful.
Please give my GitHub Projects a star βοΈ
Thanks for 32181! π€
Top comments (5)
Just so many things wrong with this. SMH
Big Will yo may share the wrong it will help us learn from.
Thanks for sharing this helpful blog!
I just finished setting up authentication with NextAuth.js in bardui.com, and it was really simple!
Glad to see that you read my article Bardui, will definitely consider your suggestions. If you found my content helpful or interesting, and youβd like to show your appreciation, why not buy me a coffee? Itβs a small gesture that goes a long way in helping me keep creating more content for you.
Just click the button below to support:
Subscribe to my YouTube Channel if you find it helpful! Subscribing is free, and it will motivate me to stay active here. π