2022-02-05 02:00:00+00:00

Securing backend API routes in a distributed microservice cluster is crucial. Instead of forcing every separate microservice (CRM, Notifications, Workflows) to implement token validation and session checks, security operations are ideally centralized at the API Gateway.

By validating JWTs at the edge, downstream microservices can focus on domain business logic, trusting the gateway to pass parsed user identities as headers.


1. Validating JWTs at the Gateway

Our gateway api-gateway intercepts all incoming requests. If a route requires authentication, it extracts the bearer token, validates the signature, check expiration, and injects user identity metadata before proxying the request:

# JWT Verification Middleware in FastAPI
import jwt
from fastapi import Request, HTTPException

JWT_SECRET = "super-secret-key"
JWT_ALGORITHM = "HS256"

async def verify_jwt_token(request: Request):
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing or invalid authorization header")
    
    token = auth_header.split(" ")[1]
    try:
        payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
        # Inject parsed user details into request scope headers
        request.scope["user"] = payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token has expired")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")

2. Header Propagation to Downstream Services

Once validated, the gateway forwards the user ID and permissions scope in custom HTTP headers (e.g., X-User-ID, X-User-Roles). Downstream microservices parse these simple headers, completely bypassing cryptographically expensive signature checks.