Lesson 93 of 158 – API Middleware
93%

API Middleware

Middleware is code that runs between the incoming API request and the final API endpoint. It can perform common tasks such as authentication, authorization, logging, validation, CORS handling, and request processing.

Note: In a PHP REST API, middleware helps keep common logic separate from individual endpoints. This makes the API easier to maintain and secure.

1. What is Middleware?

Middleware is a layer of code that processes a request before it reaches the main API endpoint.

Mobile App
    ↓
API Request
    ↓
Middleware
    ↓
API Endpoint
    ↓
Database
    ↓
JSON Response

Middleware can also process or modify the response before it is returned to the client.

2. Why Use Middleware?

Middleware is useful when the same operation is required by many API endpoints.

  • Authentication
  • Authorization
  • Logging
  • CORS handling
  • Request validation
  • Rate limiting
  • Common headers
  • Request identification

3. Middleware Request Flow

Request
   ↓
Authentication Middleware
   ↓
Authorization Middleware
   ↓
Validation Middleware
   ↓
API Controller
   ↓
Database
   ↓
Response

Each middleware can allow the request to continue or stop it.

4. Middleware Can Allow or Reject a Request

A middleware function can check a condition before allowing the request to reach the API endpoint.

if ($userIsAuthenticated) {

    // Continue to API

} else {

    // Stop request
}

For example, authentication middleware can reject a request when a valid JWT token is missing.

5. Authentication Middleware

Authentication middleware checks whether the client is properly authenticated.

Authorization: Bearer JWT_TOKEN

The middleware can extract the token, verify it, and identify the user.

6. JWT Middleware

A JWT middleware can verify the token before allowing access to protected APIs.

Request
   ↓
Read Authorization Header
   ↓
Extract JWT
   ↓
Verify JWT
   ↓
Valid?
 ↙       ↘
Yes       No
 ↓         ↓
API       401

7. Creating a Simple Authentication Middleware

A simple PHP middleware function can check for an Authorization header.

function authMiddleware()
{
    $headers = getallheaders();

    if (!isset($headers['Authorization'])) {

        http_response_code(401);

        echo json_encode([
            "success" => false,
            "message" => "Authorization required"
        ]);

        exit;
    }
}

8. Calling Middleware from an API

Middleware can be called before the main API logic.

require_once 'middleware.php';

authMiddleware();

// Protected API logic starts here

echo json_encode([
    "success" => true,
    "message" => "Protected data"
]);

9. Token Extraction

The Authorization header normally contains the Bearer token.

$headers = getallheaders();

$authHeader = $headers['Authorization'] ?? '';

if (preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {

    $token = $matches[1];

}

The extracted token can then be passed to the JWT verification logic.

10. JWT Verification Middleware

JWT verification should happen before protected API operations.

function authMiddleware()
{
    $headers = getallheaders();

    $authHeader = $headers['Authorization'] ?? '';

    if (!preg_match(
        '/Bearer\s+(.*)$/i',
        $authHeader,
        $matches
    )) {

        http_response_code(401);

        echo json_encode([
            "success" => false,
            "message" => "Token required"
        ]);

        exit;
    }

    $token = $matches[1];

    // Verify JWT here

    return $token;
}

11. Authorization Middleware

Authentication answers:

"Who are you?"

Authorization answers:

"Are you allowed to perform this operation?"

if ($userRole !== 'admin') {

    http_response_code(403);

    echo json_encode([
        "success" => false,
        "message" => "Access forbidden"
    ]);

    exit;
}

12. Role-Based Middleware

Middleware can check the user's role before allowing access.

function adminMiddleware($user)
{
    if ($user['role'] !== 'admin') {

        http_response_code(403);

        echo json_encode([
            "success" => false,
            "message" => "Admin access required"
        ]);

        exit;
    }
}

13. Logging Middleware

Logging middleware can record information about API requests.

error_log(
    $_SERVER['REQUEST_METHOD'] .
    ' ' .
    $_SERVER['REQUEST_URI']
);

Logs can help developers understand API activity and diagnose problems.

14. What Should Not Be Logged?

Never log sensitive information unnecessarily.

  • Passwords
  • JWT secrets
  • Database passwords
  • Complete authentication tokens
  • Private personal information

Log only information that is useful for debugging, monitoring, and security.

15. CORS Middleware

Middleware can also be used to add CORS headers to API responses.

header("Content-Type: application/json");
header("Access-Control-Allow-Origin: https://example.com");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

CORS configuration should be appropriate for the application's environment.

16. Handling OPTIONS Requests

Browser clients can send an OPTIONS preflight request before certain cross-origin requests.

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {

    http_response_code(204);
    exit;
}

This logic can be placed in shared middleware when required.

17. Validation Middleware

Middleware can perform common request validation before an endpoint runs.

function requireJsonRequest()
{
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';

    if (stripos($contentType, 'application/json') === false) {

        http_response_code(415);

        echo json_encode([
            "success" => false,
            "message" => "JSON request required"
        ]);

        exit;
    }
}

18. Middleware for HTTP Methods

Middleware can check whether an endpoint supports the requested HTTP method.

$allowedMethods = ['GET', 'POST'];

if (!in_array(
    $_SERVER['REQUEST_METHOD'],
    $allowedMethods,
    true
)) {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Method not allowed"
    ]);

    exit;
}

19. Rate Limiting Middleware

Rate limiting middleware can restrict how many requests a client can make within a period.

Client
  ↓
Rate Limit Middleware
  ↓
Request Count
  ↓
Limit Reached?
 ↙          ↘
No          Yes
 ↓            ↓
API          429

A production application should use a reliable shared storage mechanism for rate-limit counters.

20. Request ID Middleware

A unique request ID can help connect server logs with a particular API request.

$requestId = bin2hex(random_bytes(8));

header(
    "X-Request-ID: " . $requestId
);

error_log(
    "Request ID: " . $requestId
);

The request ID can also be returned in the API response when useful.

21. Multiple Middleware Layers

An API can use multiple middleware layers.

Request
   ↓
CORS Middleware
   ↓
Request ID Middleware
   ↓
Authentication Middleware
   ↓
Authorization Middleware
   ↓
Validation Middleware
   ↓
API Endpoint

This keeps different responsibilities separated.

22. Middleware File Structure

A PHP API can keep middleware in a separate directory.

api/
│
├── middleware/
│   ├── auth.php
│   ├── cors.php
│   ├── logging.php
│   └── validation.php
│
├── students.php
├── users.php
└── profile.php

This structure helps organize reusable API components.

23. Reusable Authentication Middleware

A reusable authentication function can be included by multiple endpoints.

// middleware/auth.php

function requireAuth()
{
    $headers = getallheaders();

    $authHeader = $headers['Authorization'] ?? '';

    if (!$authHeader) {

        http_response_code(401);

        echo json_encode([
            "success" => false,
            "message" => "Authentication required"
        ]);

        exit;
    }

    // JWT verification logic

    return true;
}

24. Using Middleware in Student API

require_once 'middleware/auth.php';

requireAuth();

$stmt = $pdo->query(
    "SELECT id, name, email
     FROM students"
);

$students = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode([
    "success" => true,
    "message" => "Students retrieved successfully",
    "data" => $students
]);

The endpoint can focus on its main student-related operation.

25. Middleware and React Native

React Native sends a normal HTTP request. The server executes middleware before returning the API response.

const response = await fetch(API_URL, {
    method: "GET",
    headers: {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    }
});

const result = await response.json();

if (response.status === 401) {
    console.log("Please login again");
}

26. Middleware Error Responses

Middleware should return the same standard response format used by the rest of the API.

http_response_code(401);

echo json_encode([
    "success" => false,
    "message" => "Authentication required",
    "data" => null
]);

exit;

This makes error handling easier in React Native.

27. Middleware Responsibilities

Middleware Responsibility
Authentication Verify user identity
Authorization Check permissions
CORS Handle cross-origin rules
Logging Record useful request information
Validation Check common request requirements
Rate Limiting Limit excessive requests

28. Middleware Execution Order

Middleware order can matter. For example, authentication must normally run before authorization because authorization needs to know who the user is.

Request
   ↓
Authentication
   ↓
Authorization
   ↓
Validation
   ↓
Controller
   ↓
Response

Choose the order according to the requirements of your API.

29. Common Middleware Mistakes

  • Putting all middleware logic inside every API file
  • Returning inconsistent error responses
  • Not stopping unauthorized requests
  • Logging passwords or tokens
  • Confusing authentication with authorization
  • Using overly broad CORS configuration
  • Not checking HTTP methods
  • Making middleware unnecessarily complex

30. API Middleware Best Practices

  • Keep middleware focused on a specific responsibility.
  • Make common middleware reusable.
  • Authenticate protected API requests.
  • Apply authorization checks where required.
  • Return standard JSON error responses.
  • Never expose sensitive information.
  • Log useful information without logging secrets.
  • Use appropriate HTTP status codes.
  • Keep API endpoint code focused on business logic.
  • Test middleware independently with Postman and the mobile application.

📌 Key Points

  • Middleware runs between the request and the API endpoint.
  • Authentication middleware can verify JWT tokens.
  • Authorization middleware can check user roles and permissions.
  • Logging middleware can record useful request information.
  • CORS and validation can also be handled through middleware.
  • Multiple middleware layers can be used in one API.
  • Reusable middleware reduces duplicate code.
  • Middleware should return standard JSON responses.
  • React Native communicates with middleware through normal API requests.
  • Keep middleware focused, reusable, secure, and easy to maintain.

🧠 Quick Quiz

Question: What is one of the main purposes of authentication middleware?