Middlewares PSR-15
Middleware řídí výkonný tok požadavků skrz aplikaci - autentifikace, validace, logování, atd.
Petrovo CMS používá vlastní implementaci PSR-15 middleware pipeline (Petrovo\Middleware) bez Laminas/Siler overhead.
Koncept
Middleware v Petrovo:
use function Petrovo\Middleware\pipe;
use function Petrovo\Route\dispatch;
use function Petrovo\Http\request;
$middleware = function($request, $handler) {
// 1. Logika PŘED handlerem
$userId = getSessionUserId();
if (!$userId && isProtectedPath($request)) {
return redirectToLogin();
}
// 2. Předej request dál
$request = $request->withAttribute('user_id', $userId);
$response = $handler->handle($request);
// 3. Logika PO handleru (úprava response)
$response = $response->withHeader('X-Runtime', microtime(true));
return $response;
};
// Zaregistruj do pipeline
pipe($middleware, 'admin');
// Middleware se aplikuje automaticky na routy s 'admin' pipeline
Klíčové body:
- Middleware dostává
ServerRequestInterfaceaRequestHandlerInterface - Voláš
$handler->handle($request)aby pokračoval do dalšího middleware - Parametry mezi middleware:
$request->withAttribute()a$request->getAttribute() - Middleware se spouští v pořadí registrace
Funkce Petrovo\Middleware
use function Petrovo\Middleware\{pipe, process, handle, reset, get_pipelines};
pipe($middleware, 'name')- Zaregistruj middleware do pipelineprocess($request, 'name')- Vrací closure pro wrappování middleware okolo handleruhandle($request, 'name')- Spustí middleware pipeline bez handlerureset()- Vyčisti všechny pipeline (testování)get_pipelines()- Debug - vrací registrované pipeline
Praktické Příklady
Jednoduchý logging middleware
// app/Middlewares/Request/loggingMiddleware.php
use function Petrovo\Middleware\pipe;
$loggingMiddleware = function ($request, $handler) {
$method = $request->getMethod();
$path = $request->getUri()->getPath();
error_log("→ $method $path");
$response = $handler->handle($request);
error_log("← " . $response->getStatusCode());
return $response;
};
// V route:
pipe($loggingMiddleware, 'admin');
Middleware s autentifikací
// app/Middlewares/Auth/authMiddleware.php
use function Petrovo\Http\text;
$authMiddleware = function ($request, $handler) {
$token = $request->getHeaderLine('Authorization');
if (!$token || !validateToken($token)) {
return text('Unauthorized', 401);
}
// Úspěšně autentifikován - pokračuj
return $handler->handle($request);
};
pipe($authMiddleware, 'api');
Middleware který mění request
// app/Middlewares/Request/userMiddleware.php
use function Petrovo\Database\DB;
$userMiddleware = function ($request, $handler) {
$userId = Session::get('user_id');
if ($userId) {
// Načti user z DB a přidej do request
$user = DB::row("SELECT * FROM users WHERE id = ?", [$userId]);
$request = $request->withAttribute('user', $user);
}
return $handler->handle($request);
};
pipe($userMiddleware, 'admin');
Middleware který mění response
// app/Middlewares/Response/securityHeadersMiddleware.php
$securityHeadersMiddleware = function ($request, $handler) {
$response = $handler->handle($request);
// Přidej security headers
return $response
->withHeader('X-Content-Type-Options', 'nosniff')
->withHeader('X-Frame-Options', 'SAMEORIGIN')
->withHeader('X-XSS-Protection', '1; mode=block')
->withHeader('Strict-Transport-Security', 'max-age=31536000');
};
pipe($securityHeadersMiddleware, 'frontend');
Implementované Middlewares
Každý middleware je v jednom souboru v adresáři dle skupin. Automaticky se loadují přes composer.json sekci "files":
{
"autoload": {
"files": [
"app/Middlewares/App/settingMiddleware.php",
"app/Middlewares/Auth/loginAdminMiddleware.php",
"app/Middlewares/Auth/loginMiddleware.php",
"app/Middlewares/Auth/logoutAdminMiddleware.php",
"app/Middlewares/Auth/logoutMiddleware.php",
"app/Middlewares/Input/adminAjaxDataMiddleware.php",
"app/Middlewares/Input/adminCubeDataMiddleware.php",
"app/Middlewares/Input/csrfMiddleware.php",
"app/Middlewares/Input/sanitizationMiddleware.php",
"app/Middlewares/Log/loggingAdminMiddleware.php",
"app/Middlewares/Request/proxyMiddleware.php",
"app/Middlewares/Response/headersMiddleware.php",
"app/Middlewares/Restriction/corsMiddleware.php",
"app/Middlewares/Restriction/ipFilteringMiddleware.php",
"app/Middlewares/Restriction/publicEndpointsMiddleware.php",
"app/Middlewares/Session/sessionExpirationAdminMiddleware.php",
"app/Middlewares/Url/defineWebMiddleware.php",
"app/Middlewares/Url/redirectionMiddleware.php"
]
}
}
Struktura middleware souboru:
<?php
declare(strict_types=1);
// $middleware = closure
$settingMiddleware = function ($request, $handler) {
// ... logika ...
return $handler->handle($request);
};
Skupiny middlewares
App
- settingMiddleware - Načítá aplikační nastavení
Auth
- loginAdminMiddleware - Ověří přihlášení admin uživatele
- loginMiddleware - Ověří přihlášení uživatele na frontendu
- logoutAdminMiddleware - Zpracuje admin odhlášení
- logoutMiddleware - Zpracuje odhlášení
Input
- adminAjaxDataMiddleware - Zpracovává AJAX data v adminu
- adminCubeDataMiddleware - Zpracovává data kostek v adminu
- csrfMiddleware - CSRF ochrana
- sanitizationMiddleware - Čistí vstupní data
Log
- loggingAdminMiddleware - Loguje akce v adminu
Request
- proxyMiddleware - při proxy nastavuje globální $_SERVER proměnné
Response
- headersMiddleware - Nastavuje response headery
Restriction
- corsMiddleware - CORS pravidla
- ipFilteringMiddleware - IP filtrování
- publicEndpointsMiddleware - Povoluje veřejné datové endpointy
Request
- sessionExpirationAdminMiddleware - kontroluje expiraci sessionu v adminu
URL
- defineWebMiddleware - Definuje web kontext (URL, jazyk, atd.)
- redirectionMiddleware - řeší přesměrovávání