0, 'path' => $adminPath, 'httponly' => true, 'secure' => request_is_https(), 'samesite' => 'Strict', ]); session_start(); define('ADMIN_LOGGED_IN', isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true); function require_admin(): void { if (!ADMIN_LOGGED_IN) { header('Location: ' . admin_url('login.php')); exit; } } function admin_url(string $page): string { return $page; } function admin_logout(): void { $_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(); header('Location: login.php'); exit; } // --------------------------------------------------------------------------- // CSRF // --------------------------------------------------------------------------- /** Per-session token, minted on first use and reused for the session's life. */ function csrf_token(): string { if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } return $_SESSION['csrf_token']; } /** Hidden field to drop into every POST form. */ function csrf_field(): string { return ''; } /** * Guard for every state-changing POST handler. Without this, any page an * admin visits while logged in could post to us on their behalf. */ function require_csrf(): void { $sent = $_POST['csrf_token'] ?? ''; if (!is_string($sent) || $sent === '' || !hash_equals(csrf_token(), $sent)) { http_response_code(403); exit('

Invalid or expired form token. ' . 'Go back, reload the page and try again.

'); } }