[auth] Doplněn úvodní komentář o všech dostupných proměnných včetně příkladů použití
This commit is contained in:
+304
-230
@@ -1,270 +1,344 @@
|
|||||||
<?php
|
<?php
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// PŘIHLAŠOVACÍ STRÁNKA
|
// HLAVNÍ SOUBOR AUTENTIZACE
|
||||||
|
// ============================================================
|
||||||
|
// Tento soubor vložíš na začátek každé stránky, kterou chceš
|
||||||
|
// chránit přihlášením:
|
||||||
|
//
|
||||||
|
// require_once 'auth/auth.php';
|
||||||
|
//
|
||||||
|
// Po jeho načtení máš k dispozici tyto proměnné:
|
||||||
|
//
|
||||||
|
// $auth_prihlasen ... true / false (vždy nastaveno)
|
||||||
|
// $auth_uzivatel['id'] ... ID přihlášeného uživatele (nebo null)
|
||||||
|
// $auth_uzivatel['email'] ... email přihlášeného uživatele (nebo null)
|
||||||
|
// $auth_uzivatel['admin'] ... true / false (vždy nastaveno)
|
||||||
|
//
|
||||||
|
// $auth_logout_html ... HTML formulář s tlačítkem "Odhlásit se"
|
||||||
|
// Neprázdný pouze pokud je uživatel přihlášen.
|
||||||
|
// Použití: echo $auth_logout_html;
|
||||||
|
//
|
||||||
|
// $auth_login_html ... HTML formulář pro přihlášení (email, heslo,
|
||||||
|
// zapamatovat si mě, CSRF token).
|
||||||
|
// Neprázdný pouze pokud uživatel NENÍ přihlášen.
|
||||||
|
// Data odesílá na AUTH_LOGIN_URL (login.php),
|
||||||
|
// které po přihlášení přesměruje zpět na
|
||||||
|
// aktuální stránku.
|
||||||
|
// Použití: echo $auth_login_html;
|
||||||
|
//
|
||||||
|
// Typické použití – stránka vyžadující přihlášení
|
||||||
|
// (VYZADOVAT_PRIHLASENI = true v config.php):
|
||||||
|
//
|
||||||
|
// <?php require_once 'auth/auth.php'; ?>
|
||||||
|
// <!-- Sem se dostane jen přihlášený uživatel. -->
|
||||||
|
// <p>Ahoj, <?php echo htmlspecialchars($auth_uzivatel['email']); ?></p>
|
||||||
|
// <?php echo $auth_logout_html; ?>
|
||||||
|
//
|
||||||
|
// Typické použití – stránka s omezeným přístupem
|
||||||
|
// (VYZADOVAT_PRIHLASENI = false v config.php):
|
||||||
|
//
|
||||||
|
// <?php require_once 'auth/auth.php'; ?>
|
||||||
|
// <?php if ($auth_prihlasen): ?>
|
||||||
|
// <p>Přihlášený obsah.</p>
|
||||||
|
// <?php echo $auth_logout_html; ?>
|
||||||
|
// <?php else: ?>
|
||||||
|
// <p>Veřejný obsah. Chceš víc? Přihlas se:</p>
|
||||||
|
// <?php echo $auth_login_html; ?>
|
||||||
|
// <?php endif; ?>
|
||||||
|
//
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Zpracovává přihlášení z dvou zdrojů:
|
|
||||||
// 1) Vlastní formulář na této stránce (login.php)
|
|
||||||
// 2) Formulář $auth_login_html vložený na jiné stránce
|
|
||||||
// (v tom případě přijde v POST i redirect_url)
|
|
||||||
|
|
||||||
require_once __DIR__ . '/config.php';
|
require_once __DIR__ . '/config.php';
|
||||||
require_once __DIR__ . '/db.php';
|
require_once __DIR__ . '/db.php';
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// SPUŠTĚNÍ SESSION
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
// Nastavíme parametry session cookie ještě PŘED session_start().
|
||||||
|
// HttpOnly = JavaScript nemůže cookie číst (ochrana před XSS)
|
||||||
|
// SameSite = cookie se neposílá při požadavcích z jiných webů
|
||||||
|
// (ochrana před CSRF)
|
||||||
|
// 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,
|
'lifetime' => 0, // 0 = cookie platí do zavření prohlížeče
|
||||||
|
// (trvalost zajišťuje remember me, ne session)
|
||||||
|
'path' => '/',
|
||||||
|
'httponly' => true, // JavaScript k cookie nemá přístup
|
||||||
|
'samesite' => 'Strict', // ochrana před CSRF
|
||||||
|
// 'secure' => true, // odkomentuj pokud web běží na HTTPS
|
||||||
|
]);
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// 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_uzivatel = [
|
||||||
|
'id' => null,
|
||||||
|
'email' => null,
|
||||||
|
'admin' => false,
|
||||||
|
];
|
||||||
|
$auth_logout_html = '';
|
||||||
|
$auth_login_html = '';
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// KROK 1: Existuje platná session?
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Session je nejrychlejší způsob ověření – nevyžaduje dotaz do DB.
|
||||||
|
// Session data jsou uložena na serveru, uživatel je nemůže zfalšovat.
|
||||||
|
|
||||||
|
if (isset($_SESSION['uzivatel_id']) && isset($_SESSION['email'])) {
|
||||||
|
|
||||||
|
// Kontrola expirace session (nečinnost)
|
||||||
|
if (isset($_SESSION['posledni_aktivita']) &&
|
||||||
|
(time() - $_SESSION['posledni_aktivita']) > SESSION_EXPIRACE) {
|
||||||
|
|
||||||
|
// Session vypršela – zrušíme ji
|
||||||
|
$_SESSION = [];
|
||||||
|
session_destroy();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Session je platná – uživatel je přihlášen
|
||||||
|
$auth_prihlasen = true;
|
||||||
|
$auth_uzivatel = [
|
||||||
|
'id' => $_SESSION['uzivatel_id'],
|
||||||
|
'email' => $_SESSION['email'],
|
||||||
|
// Přetypování na bool – ochrana pro případ, že by v session
|
||||||
|
// byla jiná hodnota než true/false
|
||||||
|
'admin' => (bool) $_SESSION['admin'],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Aktualizujeme čas poslední aktivity
|
||||||
|
$_SESSION['posledni_aktivita'] = time();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// KROK 2: Session neexistuje – zkusíme remember me cookie
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Cookie obsahuje pouze selector a token. Nikdy neobsahuje
|
||||||
|
// heslo, ID uživatele ani příznak admin. Vše citlivé je na serveru.
|
||||||
|
|
||||||
|
if (!$auth_prihlasen &&
|
||||||
|
isset($_COOKIE['auth_selector']) &&
|
||||||
|
isset($_COOKIE['auth_token'])) {
|
||||||
|
|
||||||
|
$cookie_selector = $_COOKIE['auth_selector'];
|
||||||
|
$cookie_token = $_COOKIE['auth_token'];
|
||||||
|
|
||||||
|
// Vyhledáme záznam v DB podle selectoru (přesná shoda, rychlé)
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
t.id AS token_id,
|
||||||
|
t.uzivatel_id,
|
||||||
|
t.token_hash,
|
||||||
|
t.expiruje,
|
||||||
|
u.email,
|
||||||
|
u.admin
|
||||||
|
FROM `" . DB_TABULKA_TOKENY . "` t
|
||||||
|
JOIN `" . DB_TABULKA_UZIVATELE . "` u ON u.id = t.uzivatel_id
|
||||||
|
WHERE t.selector = :selector
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([':selector' => $cookie_selector]);
|
||||||
|
$zaznam = $stmt->fetch();
|
||||||
|
|
||||||
|
$cookie_ok = false;
|
||||||
|
|
||||||
|
if ($zaznam) {
|
||||||
|
|
||||||
|
// Zkontrolujeme, zda token ještě nevypršel
|
||||||
|
if (time() < strtotime($zaznam['expiruje'])) {
|
||||||
|
|
||||||
|
// Ověříme tajný token pomocí password_verify().
|
||||||
|
// Tato funkce záměrně trvá stejně dlouho bez ohledu
|
||||||
|
// na výsledek – chrání před timing útoky.
|
||||||
|
if (password_verify($cookie_token, $zaznam['token_hash'])) {
|
||||||
|
$cookie_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cookie_ok) {
|
||||||
|
|
||||||
|
// Cookie je platná – obnovíme session
|
||||||
|
// Regenerujeme session ID (ochrana před session fixation)
|
||||||
|
session_regenerate_id(true);
|
||||||
|
|
||||||
|
$_SESSION['uzivatel_id'] = $zaznam['uzivatel_id'];
|
||||||
|
$_SESSION['email'] = $zaznam['email'];
|
||||||
|
$_SESSION['admin'] = (bool) $zaznam['admin'];
|
||||||
|
$_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_uzivatel = [
|
||||||
|
'id' => $zaznam['uzivatel_id'],
|
||||||
|
'email' => $zaznam['email'],
|
||||||
|
'admin' => (bool) $zaznam['admin'],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Prodloužíme platnost tokenu v DB i v cookie
|
||||||
|
$nova_expirace = time() + REMEMBER_EXPIRACE;
|
||||||
|
$nova_expirace_dt = date('Y-m-d H:i:s', $nova_expirace);
|
||||||
|
|
||||||
|
$stmt2 = $pdo->prepare("
|
||||||
|
UPDATE `" . DB_TABULKA_TOKENY . "`
|
||||||
|
SET `expiruje` = :expiruje
|
||||||
|
WHERE `id` = :id
|
||||||
|
");
|
||||||
|
$stmt2->execute([
|
||||||
|
':expiruje' => $nova_expirace_dt,
|
||||||
|
':id' => $zaznam['token_id'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Prodloužíme cookie v prohlížeči
|
||||||
|
setcookie('auth_selector', $cookie_selector, [
|
||||||
|
'expires' => $nova_expirace,
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Strict',
|
'samesite' => 'Strict',
|
||||||
// 'secure' => true,
|
// 'secure' => true,
|
||||||
]);
|
]);
|
||||||
session_start();
|
setcookie('auth_token', $cookie_token, [
|
||||||
|
'expires' => $nova_expirace,
|
||||||
|
'path' => '/',
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Strict',
|
||||||
|
// 'secure' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
// Pokud je uživatel již přihlášen, přesměrujeme ho rovnou dál
|
// Smažeme staré (expirované) tokeny z DB příležitostně
|
||||||
if (isset($_SESSION['uzivatel_id'])) {
|
$stmt3 = $pdo->prepare("
|
||||||
header('Location: ' . AUTH_REDIRECT_PO_PRIHLASENI);
|
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
||||||
|
WHERE `expiruje` < :ted
|
||||||
|
");
|
||||||
|
$stmt3->execute([':ted' => date('Y-m-d H:i:s')]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Cookie je neplatná nebo expirovaná – smažeme ji
|
||||||
|
if ($zaznam) {
|
||||||
|
$stmt4 = $pdo->prepare("
|
||||||
|
DELETE FROM `" . DB_TABULKA_TOKENY . "`
|
||||||
|
WHERE `id` = :id
|
||||||
|
");
|
||||||
|
$stmt4->execute([':id' => $zaznam['token_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setcookie('auth_selector', '', [
|
||||||
|
'expires' => time() - 3600,
|
||||||
|
'path' => '/',
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Strict',
|
||||||
|
]);
|
||||||
|
setcookie('auth_token', '', [
|
||||||
|
'expires' => time() - 3600,
|
||||||
|
'path' => '/',
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Strict',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// KROK 3: Rozhodnutí – přesměrovat nebo pokračovat?
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
if (!$auth_prihlasen && VYZADOVAT_PRIHLASENI) {
|
||||||
|
|
||||||
|
// Uložíme URL aktuální stránky pro přesměrování po přihlášení
|
||||||
|
$aktualni_url = $_SERVER['REQUEST_URI'] ?? '';
|
||||||
|
if (!empty($aktualni_url)) {
|
||||||
|
$_SESSION['redirect_po_prihlaseni'] = $aktualni_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: ' . AUTH_LOGIN_URL);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// CSRF TOKEN
|
// CSRF TOKEN – zajistíme, že vždy existuje
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
// Je potřebný pro oba HTML formuláře níže.
|
||||||
|
|
||||||
if (empty($_SESSION['csrf_token'])) {
|
if (empty($_SESSION['csrf_token'])) {
|
||||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||||
}
|
}
|
||||||
$csrf_token = $_SESSION['csrf_token'];
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// ZPRACOVÁNÍ FORMULÁŘE
|
// PŘIPRAVENÉ HTML PROMĚNNÉ
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
$chyba = '';
|
// -- Odhlašovací formulář ------------------------------------
|
||||||
$email_hodnota = '';
|
// Neprázdný pouze pokud je uživatel přihlášen.
|
||||||
|
// Použití na stránce: echo $auth_logout_html;
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($auth_prihlasen) {
|
||||||
|
$auth_logout_html =
|
||||||
// -- Ověření CSRF tokenu ----------------------------------
|
'<form method="POST" action="' . htmlspecialchars(AUTH_LOGOUT_URL) . '">'
|
||||||
$csrf_z_formulare = $_POST['csrf_token'] ?? '';
|
. '<input type="hidden" name="csrf_token" value="'
|
||||||
if (!hash_equals($csrf_token, $csrf_z_formulare)) {
|
. htmlspecialchars($_SESSION['csrf_token']) . '">'
|
||||||
$chyba = 'Neplatný požadavek. Zkuste stránku obnovit a přihlásit se znovu.';
|
. '<button type="submit">Odhlásit se</button>'
|
||||||
}
|
. '</form>';
|
||||||
|
|
||||||
if (empty($chyba)) {
|
|
||||||
|
|
||||||
$email = trim($_POST['email'] ?? '');
|
|
||||||
$heslo = $_POST['heslo'] ?? '';
|
|
||||||
$zapamatovat = isset($_POST['zapamatovat']);
|
|
||||||
|
|
||||||
$email_hodnota = htmlspecialchars($email);
|
|
||||||
|
|
||||||
if (empty($email) || empty($heslo)) {
|
|
||||||
$chyba = 'Zadejte email a heslo.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($chyba)) {
|
|
||||||
|
|
||||||
// -- Kontrola brute force -----------------------------
|
|
||||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
|
||||||
$okno_od = date('Y-m-d H:i:s', time() - BRUTE_OKNO);
|
|
||||||
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
SELECT COUNT(*) AS pocet
|
|
||||||
FROM `" . DB_TABULKA_BRUTE . "`
|
|
||||||
WHERE (`ip_adresa` = :ip OR `email` = :email)
|
|
||||||
AND `cas` > :okno_od
|
|
||||||
");
|
|
||||||
$stmt->execute([
|
|
||||||
':ip' => $ip,
|
|
||||||
':email' => $email,
|
|
||||||
':okno_od' => $okno_od,
|
|
||||||
]);
|
|
||||||
$pocet_pokusu = $stmt->fetch()['pocet'];
|
|
||||||
|
|
||||||
if ($pocet_pokusu >= BRUTE_MAX_POKUSU) {
|
|
||||||
$chyba = 'Příliš mnoho neúspěšných pokusů. Zkuste to prosím za chvíli.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($chyba)) {
|
|
||||||
|
|
||||||
// -- Ověření emailu a hesla v DB ----------------------
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
SELECT `id`, `email`, `heslo`, `admin`
|
|
||||||
FROM `" . DB_TABULKA_UZIVATELE . "`
|
|
||||||
WHERE `email` = :email
|
|
||||||
LIMIT 1
|
|
||||||
");
|
|
||||||
$stmt->execute([':email' => $email]);
|
|
||||||
$uzivatel = $stmt->fetch();
|
|
||||||
|
|
||||||
// I když uživatel neexistuje, zavoláme password_verify na fiktivní
|
|
||||||
// hash – aby útočník nemohl podle doby odpovědi poznat, zda email existuje
|
|
||||||
$fiktivni_hash = '$2y$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ01234';
|
|
||||||
$hash_k_overeni = $uzivatel ? $uzivatel['heslo'] : $fiktivni_hash;
|
|
||||||
$heslo_ok = password_verify($heslo, $hash_k_overeni);
|
|
||||||
|
|
||||||
if (!$uzivatel || !$heslo_ok) {
|
|
||||||
|
|
||||||
// Zapíšeme neúspěšný pokus
|
|
||||||
$stmt2 = $pdo->prepare("
|
|
||||||
INSERT INTO `" . DB_TABULKA_BRUTE . "`
|
|
||||||
(`ip_adresa`, `email`)
|
|
||||||
VALUES
|
|
||||||
(:ip, :email)
|
|
||||||
");
|
|
||||||
$stmt2->execute([
|
|
||||||
':ip' => $ip,
|
|
||||||
':email' => $email,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$chyba = 'Nesprávný email nebo heslo.';
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// -- Přihlášení úspěšné ---------------------------
|
|
||||||
session_regenerate_id(true);
|
|
||||||
|
|
||||||
$_SESSION['uzivatel_id'] = $uzivatel['id'];
|
|
||||||
$_SESSION['email'] = $uzivatel['email'];
|
|
||||||
$_SESSION['admin'] = (bool) $uzivatel['admin'];
|
|
||||||
$_SESSION['posledni_aktivita'] = time();
|
|
||||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|
||||||
|
|
||||||
// -- Remember me ----------------------------------
|
|
||||||
if ($zapamatovat) {
|
|
||||||
|
|
||||||
$selector = bin2hex(random_bytes(16));
|
|
||||||
$token = bin2hex(random_bytes(32));
|
|
||||||
$token_hash = password_hash($token, PASSWORD_DEFAULT);
|
|
||||||
$expiruje = date('Y-m-d H:i:s', time() + REMEMBER_EXPIRACE);
|
|
||||||
|
|
||||||
$stmt3 = $pdo->prepare("
|
|
||||||
INSERT INTO `" . DB_TABULKA_TOKENY . "`
|
|
||||||
(`uzivatel_id`, `selector`, `token_hash`, `expiruje`)
|
|
||||||
VALUES
|
|
||||||
(:uzivatel_id, :selector, :token_hash, :expiruje)
|
|
||||||
");
|
|
||||||
$stmt3->execute([
|
|
||||||
':uzivatel_id' => $uzivatel['id'],
|
|
||||||
':selector' => $selector,
|
|
||||||
':token_hash' => $token_hash,
|
|
||||||
':expiruje' => $expiruje,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$cookie_expirace = time() + REMEMBER_EXPIRACE;
|
|
||||||
setcookie('auth_selector', $selector, [
|
|
||||||
'expires' => $cookie_expirace,
|
|
||||||
'path' => '/',
|
|
||||||
'httponly' => true,
|
|
||||||
'samesite' => 'Strict',
|
|
||||||
// 'secure' => true,
|
|
||||||
]);
|
|
||||||
setcookie('auth_token', $token, [
|
|
||||||
'expires' => $cookie_expirace,
|
|
||||||
'path' => '/',
|
|
||||||
'httponly' => true,
|
|
||||||
'samesite' => 'Strict',
|
|
||||||
// 'secure' => true,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Přesměrování po přihlášení -------------------
|
|
||||||
// Priorita zdrojů pro redirect URL:
|
|
||||||
// 1) redirect_url z POST (formulář byl na jiné stránce)
|
|
||||||
// 2) redirect_po_prihlaseni v session (uloženo v auth.php)
|
|
||||||
// 3) výchozí stránka z config.php
|
|
||||||
$redirect_z_post = trim($_POST['redirect_url'] ?? '');
|
|
||||||
$redirect_ze_session = $_SESSION['redirect_po_prihlaseni'] ?? '';
|
|
||||||
|
|
||||||
// Bezpečnostní kontrola redirect URL:
|
|
||||||
// Povolujeme pouze relativní URL začínající lomítkem,
|
|
||||||
// aby útočník nemohl přesměrovat na cizí web
|
|
||||||
// (tzv. open redirect útok)
|
|
||||||
if (!empty($redirect_z_post) && str_starts_with($redirect_z_post, '/')) {
|
|
||||||
$redirect = $redirect_z_post;
|
|
||||||
} elseif (!empty($redirect_ze_session) && str_starts_with($redirect_ze_session, '/')) {
|
|
||||||
$redirect = $redirect_ze_session;
|
|
||||||
} else {
|
|
||||||
$redirect = AUTH_REDIRECT_PO_PRIHLASENI;
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($_SESSION['redirect_po_prihlaseni']);
|
|
||||||
|
|
||||||
header('Location: ' . $redirect);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// -- Přihlašovací formulář -----------------------------------
|
||||||
// HTML VÝSTUP
|
// Neprázdný pouze pokud uživatel NENÍ přihlášen.
|
||||||
// ------------------------------------------------------------
|
// Odesílá data na login.php, které zpracuje přihlášení
|
||||||
?>
|
// a přesměruje uživatele zpět na původní stránku.
|
||||||
<!DOCTYPE html>
|
// Použití na stránce: echo $auth_login_html;
|
||||||
<html lang="cs">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Přihlášení – <?php echo htmlspecialchars(PROJEKT_NAZEV); ?></title>
|
|
||||||
<?php if (AUTH_CSS !== ''): ?>
|
|
||||||
<link rel="stylesheet" href="<?php echo htmlspecialchars(AUTH_CSS); ?>">
|
|
||||||
<?php endif; ?>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>Přihlášení</h1>
|
if (!$auth_prihlasen) {
|
||||||
<h2><?php echo htmlspecialchars(PROJEKT_NAZEV); ?></h2>
|
|
||||||
|
|
||||||
<?php if (!empty($chyba)): ?>
|
// Aktuální URL předáme login.php jako parametr,
|
||||||
<p><strong>Chyba: <?php echo htmlspecialchars($chyba); ?></strong></p>
|
// aby nás po úspěšném přihlášení přesměroval zpět sem
|
||||||
<?php endif; ?>
|
$aktualni_url = $_SERVER['REQUEST_URI'] ?? '';
|
||||||
|
|
||||||
<form method="POST" action="">
|
$auth_login_html =
|
||||||
|
'<form method="POST" action="' . htmlspecialchars(AUTH_LOGIN_URL) . '">'
|
||||||
|
|
||||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token); ?>">
|
// CSRF token – ochrana před podvrženými požadavky
|
||||||
|
. '<input type="hidden" name="csrf_token" value="'
|
||||||
|
. htmlspecialchars($_SESSION['csrf_token']) . '">'
|
||||||
|
|
||||||
<p>
|
// Aktuální URL – login.php nás po přihlášení přesměruje zpět
|
||||||
<label for="email">Email:</label><br>
|
. '<input type="hidden" name="redirect_url" value="'
|
||||||
<input
|
. htmlspecialchars($aktualni_url) . '">'
|
||||||
type="email"
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
value="<?php echo $email_hodnota; ?>"
|
|
||||||
required
|
|
||||||
autocomplete="email"
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
. '<p>'
|
||||||
<label for="heslo">Heslo:</label><br>
|
. '<label for="auth-email">Email:</label><br>'
|
||||||
<input
|
. '<input type="email" id="auth-email" name="email"'
|
||||||
type="password"
|
. ' required autocomplete="email">'
|
||||||
id="heslo"
|
. '</p>'
|
||||||
name="heslo"
|
|
||||||
required
|
|
||||||
autocomplete="current-password"
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
. '<p>'
|
||||||
<label>
|
. '<label for="auth-heslo">Heslo:</label><br>'
|
||||||
<input type="checkbox" name="zapamatovat" value="1">
|
. '<input type="password" id="auth-heslo" name="heslo"'
|
||||||
Zapamatovat si mě
|
. ' required autocomplete="current-password">'
|
||||||
</label>
|
. '</p>'
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
. '<p>'
|
||||||
<button type="submit">Přihlásit se</button>
|
. '<label>'
|
||||||
</p>
|
. '<input type="checkbox" name="zapamatovat" value="1">'
|
||||||
|
. ' Zapamatovat si mě'
|
||||||
|
. '</label>'
|
||||||
|
. '</p>'
|
||||||
|
|
||||||
</form>
|
. '<p>'
|
||||||
|
. '<button type="submit">Přihlásit se</button>'
|
||||||
|
. '</p>'
|
||||||
|
|
||||||
<?php if (REGISTRACE_OTEVRENA): ?>
|
. '</form>';
|
||||||
<p><a href="<?php echo htmlspecialchars(AUTH_REGISTRACE_URL); ?>">Nemáš účet? Zaregistruj se.</a></p>
|
}
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<p><a href="<?php echo htmlspecialchars(AUTH_RESET_URL); ?>">Zapomněl jsi heslo?</a></p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user