Store PHP sessions in the `sessions` MySQL table (30-day TTL) instead of server files, which disappear on container restart / redeploy. Cookie lifetime also extended to 30 days. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
79 lines
2.1 KiB
PHP
79 lines
2.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/DbSessionHandler.php';
|
|
|
|
class SessionAuth
|
|
{
|
|
public static function start(): void
|
|
{
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_set_save_handler(new DbSessionHandler(), true);
|
|
session_set_cookie_params([
|
|
'lifetime' => 86400 * 30, // 30 days — survives deploys
|
|
'path' => '/',
|
|
'secure' => isset($_SERVER['HTTPS']),
|
|
'httponly' => true,
|
|
'samesite' => 'Lax',
|
|
]);
|
|
session_start();
|
|
}
|
|
}
|
|
|
|
/** Redirige a /login si no hay sesión activa. */
|
|
public static function require(): void
|
|
{
|
|
self::start();
|
|
if (empty($_SESSION['user_id'])) {
|
|
header('Location: /login');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
public static function login(array $user): void
|
|
{
|
|
self::start();
|
|
session_regenerate_id(true);
|
|
$_SESSION['user_id'] = $user['id'];
|
|
$_SESSION['user'] = [
|
|
'id' => $user['id'],
|
|
'name' => $user['name'],
|
|
'email' => $user['email'],
|
|
];
|
|
}
|
|
|
|
public static function logout(): void
|
|
{
|
|
self::start();
|
|
$_SESSION = [];
|
|
if (ini_get('session.use_cookies')) {
|
|
$p = session_get_cookie_params();
|
|
setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
|
|
}
|
|
session_destroy();
|
|
}
|
|
|
|
public static function user(): array
|
|
{
|
|
return $_SESSION['user'] ?? [];
|
|
}
|
|
|
|
public static function csrfToken(): string
|
|
{
|
|
self::start();
|
|
if (empty($_SESSION['csrf_token'])) {
|
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|
}
|
|
return $_SESSION['csrf_token'];
|
|
}
|
|
|
|
public static function validateCsrf(): void
|
|
{
|
|
$token = $_POST['_token'] ?? '';
|
|
if (!isset($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $token)) {
|
|
http_response_code(403);
|
|
exit('Token CSRF inválido.');
|
|
}
|
|
}
|
|
}
|