Objectives

1. What’s the Problem?

Each service (e.g., Product, Order) must verify the user’s identity — but we don’t want each one to manage login or passwords.

Solution: The user-service issues a JWT token, and other services verify it before processing requests.

2. Common JWT Middleware (Reusable)

In middleware/auth.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import jwt from 'jsonwebtoken';

export function verifyToken(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];

  if (!token) return res.status(401).json({ error: 'No token provided' });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(403).json({ error: 'Invalid token' });
  }
}

Add JWT_SECRET to .env of each service.

3. Protect Routes

Example in Product Service:

1
2
3
4
5
import { verifyToken } from './middleware/auth.js';

app.post('/products', verifyToken, async (req, res) => {
  // Only authenticated users can create products
});

4. Add Role-Based Access (Optional)

Add this to the middleware:

1
2
3
4
5
6
export function isAdmin(req, res, next) {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Admins only' });
  }
  next();
}

Apply like:

1
2
3
app.delete('/products/:id', verifyToken, isAdmin, async (req, res) => {
  // Only admin can delete products
});

5. Test Authentication Across Services

Use Postman or frontend to:

  1. Login → receive JWT from user-service
  2. Send request to product/order-service with:
1
Authorization: Bearer <JWT>