Middlewares PSR-15
Middleware řídí tok požadavku skrz aplikaci: auth, CSRF, session, CORS, logování, hlavičky a další cross-cutting logiku.
Petrovo CMS používá vlastní PSR-15 pipeline Core\Middleware.
Koncept
Middleware v Petrovo:
use function Core\Middleware\pipe;
use function Core\Route\dispatch;
use function Core\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 Core\Middleware
use function Core\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 Core\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 Core\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 Core\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, 'website');
Implementované middlewares
Middleware soubory se autoloadují přes composer.json sekci "files":
{
"autoload": {
"files": [
"app/Middlewares/Auth/authAdminMiddleware.php",
"app/Middlewares/Auth/permissionAdminMiddleware.php",
"app/Middlewares/Auth/authMiddleware.php",
"app/Middlewares/Input/csrfAdminMiddleware.php",
"app/Middlewares/Input/csrfMiddleware.php",
"app/Middlewares/Log/loggingAdminMiddleware.php",
"app/Middlewares/Request/proxyMiddleware.php",
"app/Middlewares/Response/headersMiddleware.php",
"app/Middlewares/Restriction/corsMiddleware.php",
"app/Middlewares/Restriction/ipBlacklistMiddleware.php",
"app/Middlewares/Restriction/ipFilteringMiddleware.php",
"app/Middlewares/Session/sessionExpirationAdminMiddleware.php",
"app/Middlewares/Url/redirectionMiddleware.php"
]
}
}
Struktura middleware souboru:
<?php
declare(strict_types=1);
// $middleware = closure
$customMiddleware = function ($request, $handler) {
// ... logika ...
return $handler->handle($request);
};
Aktuální skupiny middleware
Auth
authAdminMiddlewarekontroluje admin session a passkey login flowpermissionAdminMiddlewarehlídá admin oprávněníauthMiddlewareřeší autentizaci na frontendu
Input
csrfAdminMiddlewareověřuje CSRF v adminucsrfMiddlewareověřuje CSRF na website a/RUN
Log
loggingAdminMiddlewareloguje admin akce
Request
proxyMiddlewareupravuje request/server kontext za proxy
Response
headersMiddlewarenastavuje response hlavičky
Restriction
corsMiddlewareřeší CORSipBlacklistMiddlewareblokuje blacklistované IPipFilteringMiddlewareřeší IP omezení v jiných částech systému
Session
sessionExpirationAdminMiddlewareřeší timeout a obnovu admin session
Url
redirectionMiddlewareřeší redirect logiku starých URL