Session Management
Systém pro správu PHP sessions s vlastní konfigurací, bezpečností a logika pro expiraci.
Přehled
Petrovo CMS používá vlastní Session wrapper kolem PHP sessions. Poskytuje:
- Jednoduchou API –
Session::get(),Session::set(),Session::delete() - Automatický start – Session se spouští on-demand
- Custom session ID – Bezpečnější ID generování
- Periodic cleanup – Automatické čištění zastaralých session souborů
- Vnořené hodnoty – Přístup k nested hodnotám přes dvoutečku
user:name
Konfigurace – session.yaml
Konfigurační soubor /config/session.yaml definuje chování PHP sessions:
# Backend pro uložení sessions
save_handler: 'files'
save_path: '/var/sessions'
# Garbage collection – jak často se spustí čištění
gc_probability: 1
gc_maxlifetime: 1800 # 30 minut – maximální lifetime session
# Cookie nastavení
name: 'PHPSESSID'
cookie_httponly: true # Zákaz přístupu z JavaScript (XSS ochrana)
use_only_cookies: true # Session ID jen v cookies, ne v URL
use_strict_mode: true # Validace Session ID
use_trans_sid: false # Žádné transparent SID
cookie_secure: true # Jen HTTPS cookies
cookie_samesite: 'Strict' # CSRF ochrana (problém s card payment přesměrováním)
Bezpečnostní nastavení:
cookie_httponly: true– JavaScript nemůže číst session cookie (XSS ochrana)use_only_cookies: true– Session ID jen v cookies, ne v URLuse_strict_mode: true– Nové SID, když se přijme neznámé IDcookie_secure: true– Jen HTTPS (v produkci)cookie_samesite: 'Strict'– CSRF ochrana, ale problém s card payment přesměrováním (Proto disabled!)
Session Třída
Inicializace
use Petrovo\Session\Session;
// Session se automaticky spouští on-demand
// Nebo explicitně:
Session::start();
Co start() dělá:
- Kontroluje, zda session již běží
- Načte konfiguraci z
session.yaml - Validuje cestu pro uložení session souborů
- Generuje custom Session ID, pokud neexistuje
- Spouští session
- Provede periodic cleanup zastaralých session souborů
Metody
Session::get(string $key): mixed
Získá hodnotu z session.
use Petrovo\Session\Session;
// Jednoduché hodnoty
$userId = Session::get('user_id');
// Dot-notation pro nested values
$userName = Session::get('user:name');
$email = Session::get('user:profile:email');
// Vrátí null, pokud klíč neexistuje
$value = Session::get('non_existent'); // null
Session::set(mixed $key, mixed $value): mixed
Nastaví hodnotu v session.
// Jednoduché hodnoty
Session::set('user_id', 123);
Session::set('cart_items', 5);
// Nested hodnoty (vytvoří strukturu)
Session::set('user:name', 'John');
Session::set('user:profile:email', 'john@example.com');
// Vrátí nastavenou hodnotu
$result = Session::set('key', 'value'); // 'value'
Session::delete(mixed $key): void
Smaže hodnotu z session.
// Smazat jednoduchou hodnotu
Session::delete('user_id');
// Smazat nested hodnotu
Session::delete('user:profile'); // Smaže celý profil
Session::getAll(): array
Vrátí všechny session hodnoty.
$allData = Session::getAll();
// Vrátí: $_SESSION
var_dump($allData);
// Array (
// [user_id] => 123,
// [user] => Array([name] => 'John', ...),
// ...
// )
Příklady
Login workflow:
// Login
Session::set('user_id', $user['id']);
Session::set('user:name', $user['name']);
Session::set('user:email', $user['email']);
Session::set('admin', true);
// Použití v šablonách
$userId = Session::get('user_id');
if (Session::get('admin')) {
echo 'Přihlášený admin';
}
// Logout
Session::delete('user_id');
Session::delete('user');
Session::delete('admin');
Nákupní košík:
// Přidání do košíku
$cart = Session::get('cart') ?? [];
$cart[] = ['product_id' => 42, 'qty' => 1];
Session::set('cart', $cart);
// Počet položek v košíku
$itemCount = count(Session::get('cart') ?? []);
// Vyprázdnění košíku
Session::delete('cart');
Flash data (jednorazové zprávy):
// Nastavit flash zprávu
Session::set('flash:message', 'Změny byly uloženy!');
Session::set('flash:type', 'success');
// V šablonách
if ($message = Session::get('flash:message')) {
echo $message;
Session::delete('flash:message');
}
Middleware – Admin Session Expiration
Middleware sessionExpirationAdminMiddleware kontroluje expiraci admin session.
Umístění: /app/Middlewares/Session/sessionExpirationAdminMiddleware.php
Jak funguje
- Čte timeout z
config/session.yaml(gc_maxlifetime) - Kontroluje last activity – čas poslední aktivity v session
- Pokud vypršel timeout → vyprázdní session a přesměruje na login
- Aktualizuje last_activity – zaznamenání nové aktivity
$options = Cache::file(DIR . '/config/session.yaml');
$lifeTime = $options['gc_maxlifetime']; // 1800 sekund = 30 minut
// Kontrola expiraci
$lastActivity = Session::get('last_activity');
if (isset($lastActivity) && (time() - $lastActivity) > $lifeTime) {
// Session vypršela – logout
session_unset();
session_destroy();
redirect(loginUrl);
}
// Aktualizace aktivity
Session::set('last_activity', time());
Praktické scénáře
Scénář 1: Admin pracuje aktivně
10:00 - Admin se přihlásí
last_activity = 10:00
10:15 - Admin kliká na stránky
Middleware kontroluje: 10:15 - 10:00 = 15 minut < 30 minut (OK)
last_activity = 10:15
10:30 - Admin kliká
Middleware kontroluje: 10:30 - 10:15 = 15 minut < 30 minut (OK)
last_activity = 10:30
10:45 - Admin se neaktivní
(žádné klikání)
Scénář 2: Admin se nechal sedět
10:00 - Admin se přihlásí
last_activity = 10:00
10:40 - Admin se vrátí a kliká
Middleware kontroluje: 10:40 - 10:00 = 40 minut > 30 minut (VYPRŠELO)
Session VYPRŠELA → session_unset() → session_destroy()
Přesměrování na login
Integraci do middleware pipeline
Middleware se načítá v /app/bootstrap.php pro admin pipeline:
// app/bootstrap.php
$app->pipe('/ADMIN', sessionExpirationAdminMiddleware);
// Ostatní admin middleware...
Spouští se na každý admin request PŘED kontrolerům.
Cleanup Logika
Session soubory se akumulují na disku. Session::start() provádí periodic cleanup:
private static function cleanup(string $path, int $lifetime): void
{
$lifetime += 120; // +2 minuty buffer
$lastCleanFile = $path . '/last_clean';
if (!file_exists($lastCleanFile)) {
touch($lastCleanFile);
}
$lastCleanTimestamp = filemtime($lastCleanFile);
if (time() - $lastCleanTimestamp > $lifetime) {
touch($lastCleanFile); // Aktualizace timesteampu
}
}
Jak to funguje:
- Sleduje soubor
/var/sessions/last_clean - Pokud od poslední kontroly uplynulo víc než
gc_maxlifetime, dotkneme se souboru - PHP pak provede garbage collection (smaže staré session soubory)
Proč to takhle? – Aby se neprovádělo cleanup na každém request (drahé), ale jen periodicky.
Bezpečnostní Best Practices
Správně
// Bezpečné – session je vždy HTTP-only, HTTPS-only
Session::set('user_id', $userId);
Session::set('token', hash('sha256', $secret));
// Bezpečné – logout smaže všechna data
Session::delete('user_id');
session_destroy();
// Bezpečné – regenerace Session ID po loginu
session_regenerate_id(true);
Session::set('user_id', $userId);
Nebezpečně
// Neukládat hesla v session
Session::set('password', $plainPassword);
// Neukládat citlivé tokeny bez hashu
Session::set('api_key', $rawApiKey);
// Neměnit session ID po loginu – Session fixation útok!
Časté Problémy
Session data zmizejí
Příčina: Session timeout v gc_maxlifetime
// Kontrola v middleware
$lifeTime = 1800; // 30 minut
if (time() - $lastActivity > $lifeTime) {
// Data byla smazána!
}
Řešení: Zvýšit timeout nebo refresh stránky
Není možné zapisovat session soubory
Příčina: /var/sessions není writable
# Kontrola
ls -la var/sessions
# Oprava
chmod 755 var/sessions
Session cookie se neposílá v API
Příčina: cookie_secure: true vyžaduje HTTPS
// V .env dev prostředí
APP_ENV=dev
// A nebo vypnout cookie_secure pro dev
# config/session.yaml
cookie_secure: false # Dev only!
Konfigurace pro vývoj vs produkci
Development (.env dev)
# config/session.yaml (dev)
gc_maxlifetime: 7200 # 2 hodiny
cookie_secure: false # Bez HTTPS
cookie_samesite: 'Lax' # Tolerantní
Production (.env prod)
# config/session.yaml (prod)
gc_maxlifetime: 1800 # 30 minut (krátko!)
cookie_secure: true # Jen HTTPS
cookie_samesite: 'Strict' # Striktní
API Reference
| Metoda | Parametry | Vrací | Popis |
|---|---|---|---|
start() |
- | bool |
Spustí session, vrátí true pokud nová |
get(key) |
string |
mixed |
Získá hodnotu (dot-notation) |
getAll() |
- | array |
Vrátí všechny session hodnoty |
set(key, value) |
mixed, mixed |
mixed |
Nastaví hodnotu, vrátí ji |
delete(key) |
mixed |
void |
Smaže hodnotu |
Reference
- PHP Session Documentation
- OWASP Session Management
Session::$lifetime– Pro custom timeout (pokud potřebuješ)