main • app/auth.php
<?php
function start_session(): void {
if (session_status() === PHP_SESSION_NONE) {
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_httponly', '1');
// If you have HTTPS enabled, uncomment:
// ini_set('session.cookie_secure', '1');
ini_set('session.cookie_samesite', 'Lax');
session_start();
}
}
function csrf_token(): string {
start_session();
if (empty($_SESSION['_csrf'])) {
$_SESSION['_csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['_csrf'];
}
function csrf_verify(): void {
start_session();
$t = $_POST['_csrf'] ?? '';
if (!$t || empty($_SESSION['_csrf']) || !hash_equals($_SESSION['_csrf'], $t)) {
throw new RuntimeException("Invalid CSRF token");
}
}
function auth_user_id(): ?int {
start_session();
return isset($_SESSION['uid']) ? (int)$_SESSION['uid'] : null;
}
function require_auth(): int {
$uid = auth_user_id();
if (!$uid) {
header("Location: /login");
exit;
}
return $uid;
}
function login_user(int $userId): void {
start_session();
session_regenerate_id(true);
$_SESSION['uid'] = $userId;
}
function logout_user(): void {
start_session();
$_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();
}
function current_user(PDO $db): ?array {
$uid = auth_user_id();
if (!$uid) return null;
$st = $db->prepare("SELECT id, username, email, created_at FROM users WHERE id=? LIMIT 1");
$st->execute([$uid]);
return $st->fetch() ?: null;
}