Introduction
Authentication and authorization are critical components of any secure web application. JSON Web Tokens (JWT) is a popular way to handle authentication and authorization in a RESTful API. Let’s implement it in a Node.js project.
Prerequisites
To follow along, you should have a basic understanding of:
- JavaScript and Node.js
- Express.js
- JWT (JSON Web Tokens)
Setting Up the Project
1. Initialize the Project
First, create a new directory for your project and initialize a new Node.js project.
mkdir auth-api
cd auth-api
npm init -y
2. Install Dependencies
We’ll need the express
, jsonwebtoken
, and bcryptjs
packages to set up our server, handle JWTs, and hash passwords.
npm install express jsonwebtoken bcryptjs
Creating the Server
1. Set Up Express Server
Create a file named server.js
and set up a basic Express server.
// filepath: /auth-api/server.js
const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const app = express();
app.use(express.json());
const users = [];
const secretKey = "your-secret-key";
app.post("/register", async (req, res) => {
const { username, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
users.push({ username, password: hashedPassword });
res.status(201).json({ message: "User registered" });
});
app.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username);
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json({ message: "Invalid credentials" });
}
const token = jwt.sign({ username }, secretKey, { expiresIn: "1h" });
res.json({ token });
});
const authenticate = (req, res, next) => {
const token = req.headers["authorization"];
if (!token) {
return res.status(401).json({ message: "No token provided" });
}
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
return res.status(401).json({ message: "Failed to authenticate token" });
}
req.user = decoded;
next();
});
};
app.get("/protected", authenticate, (req, res) => {
res.json({ message: "This is a protected route", user: req.user });
});
app.listen(3000, () => {
console.log("Server is listening on port 3000");
});
Testing the API
1. Register a User
Use a tool like Postman to send a POST request to http://localhost:3000/register
with the following JSON body:
{
"username": "testuser",
"password": "password123"
}
2. Log In
Send a POST request to http://localhost:3000/login
with the following JSON body:
{
"username": "testuser",
"password": "password123"
}
You should receive a JWT token in the response.
3. Access Protected Route
Send a GET request to http://localhost:3000/protected
with the Authorization
header set to Bearer <your-token>
.
Conclusion
We just implemented basic authentication and authorization in a Node.js RESTful API using JWT. This example can be extended to include more features such as role-based access control, token refresh, and more.