Middleware
Last updated: Apr 3, 2026Table of Contents
- βοΈ What Is Middleware in Application Code?
- π§± Why Use Middleware?
- π§βπ» Example in Python (Flask Middleware)
- A simple middleware to log every request:
- π§βπ» Example in Node.js (Express)
- π§ Key Concepts
- π§© In Frameworks
- π Goal
- π§βπ» Flask Auth Middleware (Simple API Token Check)
- β app.py
- π§ͺ Test the Middleware
- β Valid request:
- β Missing token:
Great question!
βοΈ What Is Middleware in Application Code?
Middleware is a layer of code that sits between the incoming request and your core application logic. Itβs used to intercept, modify, or handle requests and responses in a web application β without changing the main business logic.
Think of it like a pipeline of functions that the request flows through:
Client β Middleware β App β Middleware β Response β Client
π§± Why Use Middleware?
Middleware lets you decouple common concerns from your core app logic, such as:
| Use Case | Description |
|---|---|
| β Authentication | Verify tokens, sessions, API keys |
| β Logging | Record request/response details |
| β Rate limiting | Prevent abuse based on IP/user |
| β CORS / Headers | Add/modify headers to handle cross-origin requests |
| β Error handling | Catch and respond to exceptions |
| β Request parsing / Validation | Ensure data is clean and safe |
π§βπ» Example in Python (Flask Middleware)
Flask lets you add middleware using before_request and after_request, or full WSGI middleware:
A simple middleware to log every request:
from flask import Flask, request
app = Flask(__name__)
@app.before_request
def log_request():
print(f"[{request.method}] {request.path}")
@app.after_request
def add_custom_header(response):
response.headers['X-App-Version'] = '1.0.0'
return response
@app.route("/hello")
def hello():
return "Hello, World!"
π§βπ» Example in Node.js (Express)
Middleware is first-class in Express β you chain them like this:
const express = require('express');
const app = express();
// Logging middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // pass control to next middleware or route
});
// Auth middleware
app.use((req, res, next) => {
if (!req.headers['authorization']) return res.status(401).send('Unauthorized');
next();
});
app.get('/api/data', (req, res) => {
res.send({ message: 'Protected data' });
});
π§ Key Concepts
- Middleware is usually stateless β it processes each request independently.
- Middleware can short-circuit the request (e.g. return 401 Unauthorized before hitting route).
- Itβs often stacked or composed, forming a pipeline.
- Can be custom or come from frameworks/libraries (e.g. Helmet, CORS, CSRF, Morgan in Express).
π§© In Frameworks
| Framework | Middleware Term |
|---|---|
| Express (Node.js) | app.use() handlers |
| Flask (Python) | @before_request, WSGI middleware |
| Django | MIDDLEWARE setting in settings.py |
| ASP.NET Core | Middleware pipeline with UseXXX() |
| Ruby on Rails | Rack middleware |
Great! Hereβs a practical example of an authentication middleware in Flask that verifies an API token from incoming requests.
π Goal
- Check for a valid
Authorizationheader - Reject unauthorized requests with a
401 Unauthorized - Allow protected routes to run only if auth passes
π§βπ» Flask Auth Middleware (Simple API Token Check)
β
app.py
from flask import Flask, request, jsonify, abort
app = Flask(__name__)
# Simulated token store (in production, use a database or external auth service)
VALID_API_TOKENS = {
"token123": "user_a",
"token456": "user_b"
}
@app.before_request
def authenticate():
# Define open (public) paths that don't need auth
public_paths = ['/health', '/login']
if request.path in public_paths:
return # skip auth check for these routes
auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
abort(401, description="Missing or malformed Authorization header")
token = auth_header.split("Bearer ")[1]
user = VALID_API_TOKENS.get(token)
if not user:
abort(401, description="Invalid or expired token")
# Attach user info to global request context
request.user = user
@app.route("/health")
def health_check():
return {"status": "ok"}
@app.route("/protected")
def protected_resource():
return {"message": f"Hello, {request.user}. You accessed a protected route."}
if __name__ == "__main__":
app.run(debug=True)
π§ͺ Test the Middleware
β Valid request:
curl -H "Authorization: Bearer token123" http://localhost:5000/protected
Response:
{
"message": "Hello, user_a. You accessed a protected route."
}
β Missing token:
curl http://localhost:5000/protected
Response:
{
"message": "Missing or malformed Authorization header"
}