Flask Middlewares

Last Updated : 2 Jun, 2026

Flask provides middleware support through request hooks, allowing applications to process requests, modify responses, and implement features like logging and authentication. Flask applications use middlewares in:

  • Checking user authentication before processing a request.
  • Capturing request details for debugging and analytics.
  • Ensuring requests meet certain criteria before reaching the main app.
  • Adding or modifying headers before sending a response.
  • Controlling request rates and preventing malicious activities.

Let's explore several ways to implement middleware in Flask applications.

Creating Custom Middleware

Flask provides hooks, which are special functions that allow you to execute code before or after processing a request. These hooks help in modifying requests, logging, authentication, and more. Two commonly used hooks for middleware are:

  • before_request: Runs before the request is processed.
  • after_request: Runs after the request is processed, modifying the response if needed.

A simple way to implement middleware in Flask is by using these hooks.

Python
from flask import Flask, request

app = Flask(__name__)

@app.before_request
def log_request():
    print(f"Incoming request: {request.method} {request.url}")

@app.after_request
def log_response(response):
    print(f"Outgoing response: {response.status_code}")
    return response

@app.route('/')
def home():
    return "Hello, Flask!"

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • @app.before_request: Middleware that handles incoming requests by executing log_request() before each request and printing the HTTP method and request URL.
  • @app.after_request: Middleware that handles outgoing responses by executing log_response(response) after each request, logging the response status code, and returning the response to complete the request cycle.

Output:

Middleware-output
Middleware Output

Every time the Flask app is refreshed, the terminal displays "Outgoing response: 200" because of the middleware. This demonstrates how middleware can handle tasks before reaching the main logic.

Middleware for Authentication and Authorization

Authentication middleware ensures that only authorized users can access specific routes. This is useful for securing APIs and web applications. Let's create a simple flask app and implement middleware for authentication and authorization in it.

Python
from flask import Flask, request, jsonify

app = Flask(__name__)

API_KEY = "my_secret_api_key"

@app.before_request
def check_authentication():
    token = request.headers.get("Authorization")
    if token != f"Bearer {API_KEY}":
        return jsonify({"error": "Unauthorized"}), 401

@app.route('/protected')
def protected():
    return jsonify({"message": "Welcome to the protected route!"})

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • before_request Middleware: Extracts the Authorization token from request headers and returns a 401 Unauthorized response if the token is missing or invalid.
  • /protected Route: A protected route that can only be accessed when a valid authentication token is provided.

Output:

We can test the application using Postman API, below is snapshot of response when a GET request is made to the /protected route with providing the header.

Middleware2
Response without authentication token

Notice that when the GET request is made to the route with the authentication token, we get a 200 OK status response. Below is the snapshot.

Middleware3
Response with authentication token

Third-Party Middleware

Instead of writing custom middleware for every feature, we can use Flask extensions or third-party libraries for advanced middleware functionalities. Some commonly used middleware libraries include:

  • Flask-CORS: Handles Cross-Origin Resource Sharing (CORS).
  • Flask-Limiter: Implements rate limiting to prevent abuse.
  • Flask-Talisman: Adds security headers for better protection.

Let's create a flask app using CORS.

Cross-Origin Resource Sharing

CORS (Cross-Origin Resource Sharing) is a security feature implemented by web browsers that restricts how resources on a web page can be requested from another domain.

For example, if your frontend (React, Vue, or plain JavaScript) is running on http://localhost:3000 and your Flask backend is running on http://127.0.0.1:5000, the browser will block requests from the frontend to the backend due to CORS policy. CORS middleware allows controlled access to your Flask API from different origins.

To use any third party middleware in application, it's required to install its module in our environment, use this command in terminal to install flask-cors:

pip install flask-cors

After installing the flask-core module, create the file app.py an paste the code below.

Python
from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)

# Allow requests only from specific frontend origins
CORS(app, origins=["http://localhost:3000", "https://myfrontend.com/"])

@app.route('/public-data')
def public_data():
    return jsonify({"message": "This data is accessible from allowed origins."})

@app.route('/private-data')
def private_data():
    return jsonify({"message": "This endpoint also follows CORS rules."})

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • CORS(app, origins=["http://localhost:3000/"]) allows only http://localhost:3000 and https://myfrontend.com/ to make API requests.
  • It enables CORS for all routes but only for allowed domains.
  • If a request comes from an unlisted domain, the browser will block it.

Using Multiple Middleware Layers

Multiple middleware functions can be used in Flask to process requests before they reach route handlers, enabling features like logging, authentication, validation, and security checks without repeating logic across routes.

Let's create a flask app that demonstrate using multiple middleware.

Python
from flask import Flask, request, jsonify

app = Flask(__name__)

API_KEY = "my_secret_api_key"

@app.before_request
def log_request():
    """ Logs incoming request details. """
    print(f"Incoming request: {request.method} {request.url}")

@app.before_request
def check_authentication():
    """ Checks if the request has a valid authentication token. """
    token = request.headers.get("Authorization")
    if token != f"Bearer {API_KEY}":
        return jsonify({"error": "Unauthorized"}), 401  # Block unauthorized requests

@app.after_request
def log_response(response):
    """ Logs outgoing response details. """
    print(f"Outgoing response: {response.status_code}")
    return response  # Must return the response object

@app.route('/secure-data')
def secure_data():
    return jsonify({"message": "Access granted to secure data."})

if __name__ == '__main__':
    app.run(debug=True)

Explanation:

  • Logging Middleware (before_request): Logs the HTTP method and URL of every incoming request to help with debugging and monitoring request flow.
  • Authentication Middleware (before_request): Extracts the Authorization token from request headers and blocks access with a 401 Unauthorized response if the token is missing or invalid.
  • Response Logging Middleware (after_request): Logs the response status code before sending the response to the client, helping track both incoming requests and outgoing responses.

Output:

Allowed Request (Valid Token)

Middleware4
Status OK

Blocked Request (No Token)

Middleware5
Status - Unauthorized Without Token

Blocked Request (Invalid Token)

Middleware6
Request logs
Comment