Middleware

What is a Middleware?

if you've used Ruby on Rails, Sinatra, express or any other modern web framework, youโ€™ve likely encountered the term Middleware.

Middleware are basically just functions that are meant to be called before our controller for that endpoint. Their purpose is simple, they will examine the request object, and from there we can modify this request object and forward it to the controller or the next middleware(yes there can be multiple middleware). Middleware can also be used as a filter. If our request body does not satisfy a particular business constraint we can simply short circuit the chain, and return a response from there without ever running the controller.

Fun fact: A controller is basically a middleware too. To be more specific its the last middleware in our chain.

Middlewares depiction

Authentication Middleware

We need to recall some things:

  • Our Posts Contract requires an authentication header to be set in the incoming request.
  • Our Posts controllers expect the user Id of the caller as req.userId.

Requirements

Now lets write the requirements for our authentication scheme.

  1. If the request object does not have an authentication header, or its value is not a valid token then we can respond with a 400, and an unauthorized access message.
  2. If the token can not be verified, then in that case we will also respond with a 400, and error message.
  3. If the token is valid, then extract the userId from it, and attach it to the request object, and forward the request to the next middleware(or controller in this case).

Implementation

Writing middlewares will vary among different frameworks, but the concept remains the same. Hereโ€™s how you can make a very basic auth middleware in express that completes all the requirements we established above.

import jwt from 'jsonwebtoken';
import { Request, Response, NextFunction } from 'express';
 
function Auth(req : Request, res : Response, next : NextFunction){
    const idToken = req.headers.authorization?.split(" ")[1];
    
    if(!idToken) return res.status(400).json({ message : "unauthorized" });
 
		const secret = "This is the secret. keep it somewhere secure"; 
    jwt.verify(idToken, secret, (err : any, payload : any) => {
      if (err) return res.status(400).json({ message : "unauthorized" });
      req.userId = (payload as { id : number }).id;
      next();
    });   
}

Notice that we have used the same secret as before.

We will later on include this middleware and associate it with each our endpoints later on in the series.

Other basic middleware

CORS(Cross-Origin Resource Sharing)

CORS is a security feature implemented in web browsers that controls how web pages from one origin can request resources from another origin. It prevents potential security vulnerabilities by enforcing restrictions on cross-origin requests. CORS headers, such as Access-Control-Allow-Origin, are set by servers to specify which origins are allowed to access their resources.

Install the following cors package from npm to get the cors middleware for express.

npm i cors

Body Parser

The bodyParser middleware is used in express to parse the incoming request body. When a client sends data to a server (e.g., in a POST request), the data is usually included in the request body. The bodyParser middleware extracts and parses this data, making it accessible in the req.body object. It's essential for handling data submitted from forms, JSON payloads, and other types of content in HTTP requests.

npm i body-parser