[FÁZE-1][config] Přidána konstanta AUTH_LOGOUT_URL
[FÁZE-1][auth] Přidána proměnná $auth_logout_html s připraveným odhlašovacím formulářem
This commit is contained in:
+53
-39
@@ -9,15 +9,17 @@
|
|||||||
//
|
//
|
||||||
// Po jeho načtení máš k dispozici tyto proměnné:
|
// Po jeho načtení máš k dispozici tyto proměnné:
|
||||||
//
|
//
|
||||||
// $auth_prihlasen ... true / false
|
// $auth_prihlasen ... true / false (vždy nastaveno)
|
||||||
// $auth_uzivatel['id'] ... ID přihlášeného uživatele
|
// $auth_uzivatel['id'] ... ID přihlášeného uživatele (nebo null)
|
||||||
// $auth_uzivatel['email'] ... email přihlášeného uživatele
|
// $auth_uzivatel['email'] ... email přihlášeného uživatele (nebo null)
|
||||||
// $auth_uzivatel['admin'] ... true / false
|
// $auth_uzivatel['admin'] ... true / false (vždy nastaveno)
|
||||||
|
// $auth_logout_html ... HTML formulář s tlačítkem odhlášení,
|
||||||
|
// nebo prázdný řetězec pokud není přihlášen
|
||||||
|
//
|
||||||
|
// Použití odhlašovacího tlačítka na chráněné stránce:
|
||||||
|
//
|
||||||
|
// echo $auth_logout_html;
|
||||||
//
|
//
|
||||||
// Pokud je v config.php VYZADOVAT_PRIHLASENI = true a uživatel
|
|
||||||
// není přihlášen, bude automaticky přesměrován na přihlašovací
|
|
||||||
// stránku. Jinak se stránka zobrazí a ty si sám rozhodneš,
|
|
||||||
// co nepřihlášenému uživateli ukážeš.
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
require_once __DIR__ . '/config.php';
|
require_once __DIR__ . '/config.php';
|
||||||
@@ -34,18 +36,20 @@ require_once __DIR__ . '/db.php';
|
|||||||
// Secure = cookie se posílá jen přes HTTPS (pokud web běží na HTTPS)
|
// Secure = cookie se posílá jen přes HTTPS (pokud web běží na HTTPS)
|
||||||
session_name(SESSION_NAZEV);
|
session_name(SESSION_NAZEV);
|
||||||
session_set_cookie_params([
|
session_set_cookie_params([
|
||||||
'lifetime' => 0, // 0 = cookie platí do zavření prohlížeče
|
'lifetime' => 0, // 0 = cookie platí do zavření prohlížeče
|
||||||
// (trvalost zajišťuje remember me, ne session)
|
// (trvalost zajišťuje remember me, ne session)
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'httponly' => true, // JavaScript k cookie nemá přístup
|
'httponly' => true, // JavaScript k cookie nemá přístup
|
||||||
'samesite' => 'Strict', // ochrana před CSRF
|
'samesite' => 'Strict', // ochrana před CSRF
|
||||||
// 'secure' => true, // odkomentuj pokud web běží na HTTPS
|
// 'secure' => true, // odkomentuj pokud web běží na HTTPS
|
||||||
]);
|
]);
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// VÝCHOZÍ STAV – uživatel není přihlášen
|
// VÝCHOZÍ STAV – uživatel není přihlášen
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
// Tyto hodnoty jsou nastaveny vždy – při každém načtení stránky.
|
||||||
|
// Teprve níže se případně přepíší na true / skutečné hodnoty.
|
||||||
|
|
||||||
$auth_prihlasen = false;
|
$auth_prihlasen = false;
|
||||||
$auth_uzivatel = [
|
$auth_uzivatel = [
|
||||||
@@ -53,19 +57,17 @@ $auth_uzivatel = [
|
|||||||
'email' => null,
|
'email' => null,
|
||||||
'admin' => false,
|
'admin' => false,
|
||||||
];
|
];
|
||||||
|
$auth_logout_html = '';
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// KROK 1: Existuje platná session?
|
// KROK 1: Existuje platná session?
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// Session je nejrychlejší způsob ověření – nevyžaduje dotaz do DB.
|
// Session je nejrychlejší způsob ověření – nevyžaduje dotaz do DB.
|
||||||
// Pokud session existuje a obsahuje uzivatel_id, uživatel je
|
// Session data jsou uložena na serveru, uživatel je nemůže zfalšovat.
|
||||||
// přihlášen. Session data jsou uložena na serveru, uživatel
|
|
||||||
// je nemůže zfalšovat.
|
|
||||||
|
|
||||||
if (isset($_SESSION['uzivatel_id']) && isset($_SESSION['email'])) {
|
if (isset($_SESSION['uzivatel_id']) && isset($_SESSION['email'])) {
|
||||||
|
|
||||||
// Kontrola expirace session (nečinnost)
|
// Kontrola expirace session (nečinnost)
|
||||||
// Pokud uživatel byl příliš dlouho neaktivní, session zrušíme
|
|
||||||
if (isset($_SESSION['posledni_aktivita']) &&
|
if (isset($_SESSION['posledni_aktivita']) &&
|
||||||
(time() - $_SESSION['posledni_aktivita']) > SESSION_EXPIRACE) {
|
(time() - $_SESSION['posledni_aktivita']) > SESSION_EXPIRACE) {
|
||||||
|
|
||||||
@@ -121,15 +123,12 @@ if (!$auth_prihlasen &&
|
|||||||
$stmt->execute([':selector' => $cookie_selector]);
|
$stmt->execute([':selector' => $cookie_selector]);
|
||||||
$zaznam = $stmt->fetch();
|
$zaznam = $stmt->fetch();
|
||||||
|
|
||||||
// Příznak, zda je cookie platná
|
|
||||||
$cookie_ok = false;
|
$cookie_ok = false;
|
||||||
|
|
||||||
if ($zaznam) {
|
if ($zaznam) {
|
||||||
|
|
||||||
// Zkontrolujeme, zda token ještě nevypršel
|
// Zkontrolujeme, zda token ještě nevypršel
|
||||||
$expiruje_timestamp = strtotime($zaznam['expiruje']);
|
if (time() < strtotime($zaznam['expiruje'])) {
|
||||||
|
|
||||||
if (time() < $expiruje_timestamp) {
|
|
||||||
|
|
||||||
// Ověříme tajný token pomocí password_verify().
|
// Ověříme tajný token pomocí password_verify().
|
||||||
// Tato funkce záměrně trvá stejně dlouho bez ohledu
|
// Tato funkce záměrně trvá stejně dlouho bez ohledu
|
||||||
@@ -143,14 +142,19 @@ if (!$auth_prihlasen &&
|
|||||||
if ($cookie_ok) {
|
if ($cookie_ok) {
|
||||||
|
|
||||||
// Cookie je platná – obnovíme session
|
// Cookie je platná – obnovíme session
|
||||||
// Nejprve regenerujeme session ID (ochrana před session fixation)
|
// Regenerujeme session ID (ochrana před session fixation)
|
||||||
session_regenerate_id(true);
|
session_regenerate_id(true);
|
||||||
|
|
||||||
$_SESSION['uzivatel_id'] = $zaznam['uzivatel_id'];
|
$_SESSION['uzivatel_id'] = $zaznam['uzivatel_id'];
|
||||||
$_SESSION['email'] = $zaznam['email'];
|
$_SESSION['email'] = $zaznam['email'];
|
||||||
$_SESSION['admin'] = (bool) $zaznam['admin'];
|
$_SESSION['admin'] = (bool) $zaznam['admin'];
|
||||||
$_SESSION['posledni_aktivita'] = time();
|
$_SESSION['posledni_aktivita'] = time();
|
||||||
|
|
||||||
|
// Vygenerujeme CSRF token pokud ještě neexistuje
|
||||||
|
if (empty($_SESSION['csrf_token'])) {
|
||||||
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||||
|
}
|
||||||
|
|
||||||
$auth_prihlasen = true;
|
$auth_prihlasen = true;
|
||||||
$auth_uzivatel = [
|
$auth_uzivatel = [
|
||||||
'id' => $zaznam['uzivatel_id'],
|
'id' => $zaznam['uzivatel_id'],
|
||||||
@@ -178,18 +182,17 @@ if (!$auth_prihlasen &&
|
|||||||
'path' => '/',
|
'path' => '/',
|
||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Strict',
|
'samesite' => 'Strict',
|
||||||
// 'secure' => true, // odkomentuj pokud web běží na HTTPS
|
// 'secure' => true,
|
||||||
]);
|
]);
|
||||||
setcookie('auth_token', $cookie_token, [
|
setcookie('auth_token', $cookie_token, [
|
||||||
'expires' => $nova_expirace,
|
'expires' => $nova_expirace,
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Strict',
|
'samesite' => 'Strict',
|
||||||
// 'secure' => true, // odkomentuj pokud web běží na HTTPS
|
// 'secure' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Smažeme staré (expirované) tokeny z DB
|
// Smažeme staré (expirované) tokeny z DB příležitostně
|
||||||
// Děláme to zde příležitostně, aby se DB neplnila starými záznamy
|
|
||||||
$stmt3 = $pdo->prepare("
|
$stmt3 = $pdo->prepare("
|
||||||
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
||||||
WHERE `expiruje` < :ted
|
WHERE `expiruje` < :ted
|
||||||
@@ -198,8 +201,7 @@ if (!$auth_prihlasen &&
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Cookie je neplatná nebo expirovaná – smažeme ji z prohlížeče
|
// Cookie je neplatná nebo expirovaná – smažeme ji
|
||||||
// i případný záznam z DB (pokud selector existoval)
|
|
||||||
if ($zaznam) {
|
if ($zaznam) {
|
||||||
$stmt4 = $pdo->prepare("
|
$stmt4 = $pdo->prepare("
|
||||||
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
||||||
@@ -208,7 +210,6 @@ if (!$auth_prihlasen &&
|
|||||||
$stmt4->execute([':id' => $zaznam['token_id']]);
|
$stmt4->execute([':id' => $zaznam['token_id']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smažeme cookies nastavením expirace do minulosti
|
|
||||||
setcookie('auth_selector', '', [
|
setcookie('auth_selector', '', [
|
||||||
'expires' => time() - 3600,
|
'expires' => time() - 3600,
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
@@ -230,18 +231,31 @@ if (!$auth_prihlasen &&
|
|||||||
|
|
||||||
if (!$auth_prihlasen && VYZADOVAT_PRIHLASENI) {
|
if (!$auth_prihlasen && VYZADOVAT_PRIHLASENI) {
|
||||||
|
|
||||||
// Uložíme URL aktuální stránky, aby se uživatel mohl po
|
// Uložíme URL aktuální stránky pro přesměrování po přihlášení
|
||||||
// přihlášení vrátit tam, kde byl
|
|
||||||
$aktualni_url = $_SERVER['REQUEST_URI'] ?? '';
|
$aktualni_url = $_SERVER['REQUEST_URI'] ?? '';
|
||||||
if (!empty($aktualni_url)) {
|
if (!empty($aktualni_url)) {
|
||||||
$_SESSION['redirect_po_prihlaseni'] = $aktualni_url;
|
$_SESSION['redirect_po_prihlaseni'] = $aktualni_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Přesměujeme na přihlašovací stránku
|
|
||||||
header('Location: ' . AUTH_LOGIN_URL);
|
header('Location: ' . AUTH_LOGIN_URL);
|
||||||
exit;
|
exit;
|
||||||
|
}
|
||||||
// Pokud je VYZADOVAT_PRIHLASENI = false, skript pokračuje dál.
|
|
||||||
// Stránka pak sama rozhodne, co nepřihlášenému uživateli ukáže,
|
// ------------------------------------------------------------
|
||||||
// pomocí proměnných $auth_prihlasen a $auth_uzivatel.
|
// PŘIPRAVENÝ HTML KÓD PRO ODHLAŠOVACÍ TLAČÍTKO
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Na chráněné stránce stačí napsat:
|
||||||
|
//
|
||||||
|
// echo $auth_logout_html;
|
||||||
|
//
|
||||||
|
// Pokud uživatel není přihlášen, proměnná je prázdný řetězec
|
||||||
|
// a nevypíše se nic.
|
||||||
|
|
||||||
|
if ($auth_prihlasen) {
|
||||||
|
$auth_logout_html =
|
||||||
|
'<form method="POST" action="' . htmlspecialchars(AUTH_LOGOUT_URL) . '">'
|
||||||
|
. '<input type="hidden" name="csrf_token" value="'
|
||||||
|
. htmlspecialchars($_SESSION['csrf_token'] ?? '') . '">'
|
||||||
|
. '<button type="submit">Odhlásit se</button>'
|
||||||
|
. '</form>';
|
||||||
}
|
}
|
||||||
@@ -50,6 +50,9 @@ define('PROJEKT_URL', 'https://example.com');
|
|||||||
// Cesta k přihlašovací stránce (relativní od kořene projektu)
|
// Cesta k přihlašovací stránce (relativní od kořene projektu)
|
||||||
define('AUTH_LOGIN_URL', '/auth/login.php');
|
define('AUTH_LOGIN_URL', '/auth/login.php');
|
||||||
|
|
||||||
|
// Cesta k odhlašovací stránce (relativní od kořene projektu)
|
||||||
|
define('AUTH_LOGOUT_URL', '/auth/logout.php');
|
||||||
|
|
||||||
// Cesta k hlavní stránce po přihlášení
|
// Cesta k hlavní stránce po přihlášení
|
||||||
define('AUTH_REDIRECT_PO_PRIHLASENI', '/index.php');
|
define('AUTH_REDIRECT_PO_PRIHLASENI', '/index.php');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user