Skip to content

JWT Authentication Middleware

Relevant source files - controllers/auth.controller.js - controllers/user.controller.js - middlewares/auth.middleware.js

The authorize middleware is the primary security gatekeeper for protected routes in the Subscription Tracker API. It implements stateless authentication using JSON Web Tokens (JWT) to verify the identity of requesting clients and populate user context for downstream handlers.

Implementation Overview

The middleware is defined in middlewares/auth.middleware.js5-35 It intercept incoming requests to validate the presence and integrity of a Bearer token. Upon successful validation, it retrieves the associated user from the MongoDB database—excluding sensitive fields—and attaches the user object to the req (request) object.

Logic Flow Diagram: Request Authorization

The following diagram illustrates the sequence of operations performed by the authorize middleware when a request hits a protected endpoint.

Middleware Sequence

sequenceDiagram
    participant Client
    participant authorize as "authorize (auth.middleware.js)"
    participant JWT as "jsonwebtoken.verify"
    participant DB as "User Model (MongoDB)"
    participant Next as "Next Middleware/Controller"
    Client->>authorize: Request with "Authorization: Bearer <token>"
    authorize-->>Client: 401 Unauthorized
    authorize->>JWT: verify(token, JWT_SECRET)
    JWT-->>authorize: Throw Error
    authorize-->>Client: 401 Unauthorized
    JWT->>authorize: Return decoded payload { userId }
    authorize->>DB: findById(userId).select("-password")
    DB-->>authorize: null
    authorize-->>Client: 401 Unauthorized
    DB-->>authorize: userObject
    authorize->>authorize: Set req.user = userObject
    authorize->>Next: next()

Sources:middlewares/auth.middleware.js5-35controllers/auth.controller.js38-40controllers/auth.controller.js80-82

Key Technical Components

1. Token Extraction

The middleware looks for the token in the Authorization header. It specifically expects the Bearer schema middlewares/auth.middleware.js9-10 If the header is missing or does not start with "Bearer", the middleware immediately terminates the request with a 401 Unauthorized response middlewares/auth.middleware.js12-15

2. JWT Verification

The extraction process yields a string which is then verified using jwt.verify() against the JWT_SECRET loaded from environment variables middlewares/auth.middleware.js17

3. Identity Resolution & Security

Once the userId is decoded, the middleware queries the database to ensure the user still exists middlewares/auth.middleware.js19

  • Password Exclusion: To maintain security, the query uses .select("-password") to ensure the hashed password never enters the request context or subsequent logs middlewares/auth.middleware.js19
  • Request Population: If found, the user document is assigned to req.usermiddlewares/auth.middleware.js26 This allows controllers to access the authenticated user's data (e.g., req.user._id) without performing redundant database lookups.

Code Entity Mapping

[Flowchart Diagram]

Sources:middlewares/auth.middleware.js1-35config/env.js5

Error Responses

The middleware enforces a strict "fail-fast" policy for authentication.

Scenario HTTP Status Response Body
Missing Authorization header 401 {"message": "Unauthorized"}
Token does not start with "Bearer" 401 {"message": "Unauthorized"}
Expired or Invalid JWT 401 {"message": "Unauthorized", "error": "..."}
Valid JWT but User deleted from DB 401 {"message": "Unauthorized"}

Sources:middlewares/auth.middleware.js12-15middlewares/auth.middleware.js21-24middlewares/auth.middleware.js29-34

Usage in Routing

The authorize middleware is imported and placed before controller logic in route definitions. For example, in the User API, it protects the "Get All Users" endpoint:

  • File:routes/user.routes.js (referenced by controllers/user.controller.js3)
  • Action: It ensures that only users with a valid token can fetch the list of all registered users.

Sources:middlewares/auth.middleware.js38controllers/user.controller.js3-13