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"