go-learn/server/lib/auth.php
sab.code.lab 1c85091186 chore: восстановление репозитория из снапшота v0.3.1
Прежняя git-история утрачена при переносе проекта на машину владельца
(снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной
истории.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 09:34:02 +02:00

99 lines
2.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* Сессии и текущий пользователь.
* PHP native-сессии, cookie HttpOnly, SameSite=Lax, Secure при HTTPS.
*/
/**
* Старт сессии с параметрами cookie по контракту.
* Идемпотентно (повторный вызов безопасен).
*/
function session_start_secure(): void
{
if (session_status() === PHP_SESSION_ACTIVE) {
return;
}
// Fallback save_path (пустой/несуществующий/недоступный — типично для
// ручных сборок и части shared-хостингов): уходим в sys_get_temp_dir().
$savePath = (string)ini_get('session.save_path');
if (
$savePath === ''
|| !is_dir($savePath)
|| !is_writable($savePath)
) {
ini_set('session.save_path', sys_get_temp_dir());
}
$https = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
session_set_cookie_params([
'path' => '/',
'httponly' => true,
'samesite' => 'Lax',
'secure' => $https,
]);
session_start();
}
/**
* Текущий пользователь по сессии или null.
*
* @return array{id: int, email: string}|null
*/
function current_user(PDO $pdo): ?array
{
session_start_secure();
$id = $_SESSION['user_id'] ?? null;
if (!is_int($id)) {
return null;
}
$stmt = $pdo->prepare('SELECT id, email FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch();
if (!is_array($user)) {
return null;
}
return ['id' => (int)$user['id'], 'email' => (string)$user['email']];
}
/**
* Текущий пользователь или 401.
*
* @return array{id: int, email: string}
*/
function require_user(PDO $pdo): array
{
$user = current_user($pdo);
if ($user === null) {
error_out(401, 'unauthorized');
}
return $user;
}
/** Установить сессию после успешного login (id перегенерируется). */
function login_user(int $id): void
{
session_start_secure();
session_regenerate_id(true);
$_SESSION['user_id'] = $id;
}
/** Полный выход: очистка $_SESSION, cookie и уничтожение сессии. */
function logout_user(): void
{
session_start_secure();
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', [
'expires' => time() - 42000,
'path' => $params['path'],
'domain' => $params['domain'],
'secure' => $params['secure'],
'httponly' => $params['httponly'],
'samesite' => $params['samesite'] ?? 'Lax',
]);
}
session_destroy();
}