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 → ResponseCommon 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 executesImportant: 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!