Building a Secure API with OAuth 2.0 and JWT in Express.js
In today's digital landscape, securing APIs is more crucial than ever. As developers, we need robust mechanisms to protect sensitive data and manage user authentication efficiently. In this article, we’ll explore how to build a secure API using OAuth 2.0 and JSON Web Tokens (JWT) in Express.js. We'll provide step-by-step instructions, code snippets, and actionable insights to help you implement a secure authentication system.
What is OAuth 2.0?
OAuth 2.0 is an authorization framework that allows third-party applications to obtain limited access to an HTTP service. It enables users to share their private resources (like photos or contacts) stored on one site with another site without having to hand out their credentials.
Use Cases of OAuth 2.0
- Third-party integrations: Allowing users to log in using their Google or Facebook accounts.
- Mobile app authentication: Granting limited access to APIs for mobile applications.
- Single sign-on (SSO): Enabling users to authenticate across multiple applications with one set of credentials.
What is JSON Web Token (JWT)?
JWT is a compact, URL-safe means of representing claims to be transferred between two parties. It consists of three parts: a header, a payload, and a signature. The signature ensures that the sender of the JWT is who it claims to be and that the message wasn’t changed along the way.
Use Cases of JWT
- Session management: Maintaining user sessions in web applications.
- Information exchange: Securely transmitting information between parties.
- Authentication: Verifying user identity in stateless applications.
Setting Up the Project
Let's get started by setting up a new Express.js project. Make sure you have Node.js and npm installed on your machine.
Step 1: Initialize the Project
mkdir secure-api
cd secure-api
npm init -y
Step 2: Install Required Packages
We’ll need several packages to get started:
- Express: Our web framework.
- jsonwebtoken: For creating and verifying JWTs.
- dotenv: For managing environment variables.
- body-parser: To parse incoming request bodies.
Install these packages using npm:
npm install express jsonwebtoken dotenv body-parser
Step 3: Create a Basic Express Server
Create a file named server.js
and set up a basic Express server:
const express = require('express');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
dotenv.config();
const app = express();
app.use(bodyParser.json());
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Implementing OAuth 2.0 with JWT
Step 4: Creating Authentication Routes
We will create two routes: one for logging in and another for accessing protected resources.
Add the following code to server.js
:
const users = [
{ id: 1, username: 'user1', password: 'password1' },
{ id: 2, username: 'user2', password: 'password2' }
];
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);
if (!user) {
return res.status(401).send('Invalid credentials');
}
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.json({ token });
});
Step 5: Protecting Routes with JWT Middleware
Now, we need to create middleware to protect our routes. This middleware will verify the JWT token sent from the client.
Add the following code to server.js
:
const jwt = require('jsonwebtoken');
function authenticateToken(req, res, next) {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) return res.sendStatus(401);
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
app.get('/protected', authenticateToken, (req, res) => {
res.json({ message: 'This is a protected route', user: req.user });
});
Testing the API
Step 6: Testing with Postman
-
Start your server:
bash node server.js
-
Use Postman to test your API:
- Login:
- Method: POST
- URL:
http://localhost:3000/login
- Body:
json { "username": "user1", "password": "password1" }
- Access Protected Route:
- Method: GET
- URL:
http://localhost:3000/protected
- Headers:
Authorization: Bearer <your_token_here>
Conclusion
Building a secure API with OAuth 2.0 and JWT in Express.js is an essential skill for modern web development. By following the steps outlined in this article, you can ensure that your API is protected against unauthorized access and that user sessions are managed securely.
Key Takeaways
- OAuth 2.0 provides a robust framework for third-party application authorization.
- JWT enables secure information exchange and stateless authentication.
- Implementing middleware in Express.js helps protect your API routes effectively.
With these tools and techniques, you can create a secure API that stands up to modern security challenges. Happy coding!