fix: persist admin sessions in DB so deploys don't log out users

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>
This commit is contained in:
Lizandro Guarnizo
2026-06-30 18:42:33 -05:00
co-authored by Claude Sonnet 4.6
parent b288b07ff5
commit 37eef6a705
2 changed files with 42 additions and 1 deletions
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
class DbSessionHandler implements SessionHandlerInterface
{
private const TTL = 86400 * 30; // 30 days
public function open(string $path, string $name): bool { return true; }
public function close(): bool { return true; }
public function read(string $id): string|false
{
$stmt = db()->prepare("SELECT data FROM sessions WHERE id = ? AND updated_at > DATE_SUB(NOW(), INTERVAL " . self::TTL . " SECOND)");
$stmt->execute([$id]);
$row = $stmt->fetch();
return $row ? $row['data'] : '';
}
public function write(string $id, string $data): bool
{
db()->prepare("INSERT INTO sessions (id, data) VALUES (?, ?) ON DUPLICATE KEY UPDATE data = VALUES(data), updated_at = NOW()")
->execute([$id, $data]);
return true;
}
public function destroy(string $id): bool
{
db()->prepare("DELETE FROM sessions WHERE id = ?")->execute([$id]);
return true;
}
public function gc(int $max_lifetime): int|false
{
$stmt = db()->prepare("DELETE FROM sessions WHERE updated_at < DATE_SUB(NOW(), INTERVAL ? SECOND)");
$stmt->execute([self::TTL]);
return $stmt->rowCount();
}
}
+4 -1
View File
@@ -1,13 +1,16 @@
<?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' => 0,
'lifetime' => 86400 * 30, // 30 days — survives deploys
'path' => '/',
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true,