DALT.PHP

Middleware Pipeline

Learn how to filter requests before they reach controllers

Lesson 3: Middleware Pipeline

Middleware acts as a filter between the incoming request and your controller, allowing you to inspect, modify, or reject requests.

What is Middleware?

Middleware is code that runs before your controller executes:

Request → Middleware → Controller → Response

Common uses:

  • Authentication - Ensure user is logged in
  • Authorization - Check user permissions
  • CSRF Protection - Validate form tokens
  • Logging - Record request details
  • Rate Limiting - Prevent abuse

Defining Middleware

Middleware classes have a handle() method:

namespace Core\Middleware;

class Auth {
    public function handle() {
        if (!isset($_SESSION['user'])) {
            redirect('/login');
        }
    }
}

Applying Middleware

Use the only() method on routes:

// Single middleware
$router->get('/dashboard', 'dashboard.php')->only('auth');

// Multiple middleware
$router->post('/posts', 'posts/store.php')->only(['auth', 'csrf']);

Execution Order

Middleware runs in the order specified:

$router->post('/update', 'update.php')->only(['auth', 'csrf']);

// Execution:
// 1. Auth middleware checks login
// 2. CSRF middleware validates token
// 3. Controller executes

Important: If any middleware fails (redirects or aborts), the chain stops and the controller never executes.

Built-in Middleware

Auth Middleware

Requires authenticated user:

class Auth {
    public function handle() {
        if (!isset($_SESSION['user'])) {
            redirect('/login');
        }
    }
}

Usage:

$router->get('/dashboard', 'dashboard.php')->only('auth');

Guest Middleware

Requires unauthenticated user:

class Guest {
    public function handle() {
        if (isset($_SESSION['user'])) {
            redirect('/dashboard');
        }
    }
}

Usage:

$router->get('/login', 'auth/login.php')->only('guest');

CSRF Middleware

Validates CSRF tokens on form submissions:

class Csrf {
    public function handle() {
        $token = $_POST['_token'] ?? '';
        $sessionToken = $_SESSION['_token'] ?? '';
        
        if (!hash_equals($sessionToken, $token)) {
            abort(403);
        }
    }
}

Usage:

$router->post('/posts', 'posts/store.php')->only(['auth', 'csrf']);

In your form:

<form method="POST">
    <?= csrf_field() ?>
    <!-- form fields -->
</form>

Middleware Registration

Middleware is registered in the MAP constant:

// framework/Core/Middleware/Middleware.php
const MAP = [
    'auth' => Auth::class,
    'guest' => Guest::class,
    'csrf' => Csrf::class,
];

Creating Custom Middleware

Step 1: Create Middleware Class

// framework/Core/Middleware/Admin.php
namespace Core\Middleware;

class Admin {
    public function handle() {
        if (!isset($_SESSION['user']['is_admin'])) {
            abort(403);
        }
    }
}

Step 2: Register in MAP

const MAP = [
    'auth' => Auth::class,
    'guest' => Guest::class,
    'csrf' => Csrf::class,
    'admin' => Admin::class, // Add here
];

Step 3: Use in Routes

$router->get('/admin', 'admin/dashboard.php')->only(['auth', 'admin']);

Common Patterns

Protected Routes

// Require login
$router->get('/profile', 'profile.php')->only('auth');

// Require login + CSRF for forms
$router->post('/profile', 'profile/update.php')->only(['auth', 'csrf']);

Public Routes

// No middleware needed
$router->get('/', 'welcome.php');
$router->get('/about', 'about.php');

Guest-Only Routes

// Redirect logged-in users away
$router->get('/login', 'auth/login.php')->only('guest');
$router->get('/register', 'auth/register.php')->only('guest');

Debugging Middleware

Check Execution

// In middleware handle() method
dd('Auth middleware executed');

Verify Session

// Check what's in session
dd($_SESSION);

Test Middleware Order

// Add to each middleware
error_log('Auth middleware');
error_log('CSRF middleware');

Common Issues

Middleware Not Running

Causes:

  • Middleware not registered in MAP
  • Wrong middleware key in only()
  • Route doesn't have only() call

Wrong Execution Order

Causes:

  • Middleware array order is wrong
  • Check the order in only(['first', 'second'])

Infinite Redirects

Causes:

  • Auth middleware redirects to login
  • Login route also has auth middleware
  • Solution: Use guest middleware on login

Common Bug: Don't put auth middleware on login/register routes!

Ready for the Challenge?

On this page