Skip to content

Implementing Authentication and Authorization in Node.js with JWT

Published: at 01:00 PMSuggest Changes

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.