Zum Skriptum
Skriptum 04

Vertiefungsübungen

PHP Cookies – Praxisszenarien

Was du in dieser Aufgabe uebst

Cookies manipulieren

Du aenderst, loeschst und verwaltest bestehende Cookies

Security Flags

Du setzt httponly, secure und SameSite Optionen

Cookie-Sicherheit

Du verstehst Sicherheitsrisiken und wie man sie vermeidet

Hinweis zur Bearbeitung

Diese Aufgaben bauen auf den Grundlagen (Übungsblatt 1) auf und zeigen, wie Cookies in realen Szenarien eingesetzt werden. Erstelle für jede Aufgabe eine eigene .php-Datei in htdocs/ und öffne sie über http://localhost/.

Aufgabe 1

Alle Cookies anzeigen

Einfach

Erstelle eine Datei alle_cookies.php, die alle aktuell gesetzten Cookies des Browsers in einer HTML-Tabelle ausgibt.

  • Die Tabelle soll zwei Spalten haben: Name und Wert.
  • Falls keine Cookies vorhanden sind, zeige den Text: „Keine Cookies gesetzt."
  • Alle Ausgaben müssen mit htmlspecialchars() gesichert werden.
Tipp: Das superglobale Array $_COOKIE enthält alle Cookies als Schlüssel-Wert-Paare. Mit foreach ($array as $key => $value) kannst du es durchlaufen.
<!DOCTYPE html>
<html lang="de"><body>
<h1>Meine Cookies</h1>

<?php if (empty($_COOKIE)): ?>
    <p>Keine Cookies gesetzt.</p>
<?php else: ?>
    <table border="1">
        <tr><th>Name</th><th>Wert</th></tr>
        <?php foreach ($_COOKIE as $name => $wert): ?>
        <tr>
            <td><?= htmlspecialchars($name) ?></td>
            <td><?= htmlspecialchars($wert) ?></td>
        </tr>
        <?php endforeach; ?>
    </table>
<?php endif; ?>
</body></html>
Aufgabe 2

Farbschema-Einstellung speichern

Mittel

Erstelle eine Datei farbschema.php, die die Farbschema-Präferenz des Benutzers in einem Cookie speichert.

  • Die Seite zeigt ein Formular mit einem <select>-Feld: Optionen hell und dunkel.
  • Nach dem Absenden (POST) wird die gewählte Option im Cookie farbschema für 30 Tage gespeichert.
  • Die Seite liest den Cookie aus und setzt die CSS-Hintergrundfarbe entsprechend: hell → weißer Hintergrund, dunkel → dunkler Hintergrund (#1e293b, helle Schrift).
  • Das <select>-Feld soll die aktuell gespeicherte Option vorauswählen.
Wichtig – Validierung: Prüfe, ob der gesendete Wert wirklich hell oder dunkel ist, bevor du ihn im Cookie speicherst. Nutze dafür in_array(). Nur validierte Werte dürfen gespeichert werden!
<?php
// Erlaubte Werte – kein anderer Wert darf gespeichert werden
$erlaubteWerte = ['hell', 'dunkel'];

// Formular verarbeiten (POST)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $wahl = $_POST['schema'] ?? '';
    if (in_array($wahl, $erlaubteWerte, true)) {
        setcookie('farbschema', $wahl, time() + 30 * 24 * 3600);
        // Sofort anwenden (Cookie gilt erst beim nächsten Request)
        $_COOKIE['farbschema'] = $wahl;
    }
}

// Aktuelles Schema lesen (Fallback: 'hell')
$schema = $_COOKIE['farbschema'] ?? 'hell';
if (!in_array($schema, $erlaubteWerte, true)) {
    $schema = 'hell'; // Manipulierte Cookies ignorieren
}

$bgCss = $schema === 'dunkel'
    ? 'background:#1e293b;color:#f8fafc;'
    : 'background:#ffffff;color:#334155;';
?>
<!DOCTYPE html>
<html>
<body style="<?= $bgCss ?>">
    <h1>Farbschema-Einstellung</h1>
    <p>Aktives Schema: <?= htmlspecialchars($schema) ?></p>
    <form method="post">
        <select name="schema">
            <option value="hell" <?= $schema==='hell' ? 'selected' : '' ?>>Hell</option>
            <option value="dunkel" <?= $schema==='dunkel' ? 'selected' : '' ?>>Dunkel</option>
        </select>
        <button type="submit">Speichern</button>
    </form>
</body></html>

Nach setcookie() ist der neue Wert in $_COOKIE noch nicht sichtbar – er gilt erst beim nächsten Request. Durch das manuelle Setzen von $_COOKIE['farbschema'] = $wahl wird er sofort auf der aktuellen Seite wirksam.

Aufgabe 3

Cookie-basiertes Login

Mittel

Simuliere ein einfaches Login-System mit zwei Dateien: login.php und dashboard.php.

login.php
  • Zeigt ein Formular mit Feldern für Benutzername und Passwort.
  • Prüft nach dem Absenden: admin / geheim → Login erfolgreich.
  • Bei Erfolg: Cookie eingeloggt mit Wert 1 setzen (1 Stunde Gültigkeit), danach Weiterleitung zu dashboard.php via header("Location: ...").
  • Bei falschem Passwort: Fehlermeldung anzeigen.
dashboard.php
  • Prüft, ob der Cookie eingeloggt gesetzt und gleich 1 ist.
  • Falls ja: Zeigt „Willkommen im Dashboard!" und einen Logout-Link.
  • Falls nein: Sofort Weiterleitung zu login.php.
  • Logout-Link: ruft logout.php auf, das den Cookie löscht und zurück zu login.php leitet.
⚠ Wichtiger Hinweis – Nur zur Übung! Dieses System ist nicht produktionssicher: Passwörter im Code sind gefährlich, Cookies können manipuliert werden. In echten Anwendungen verwendet man Sessions und gehashte Passwörter (password_hash()). Hier geht es nur darum, die Cookie-Mechanik zu verstehen.

login.php

<?php
$fehler = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $user = $_POST['benutzer'] ?? '';
    $pass = $_POST['passwort'] ?? '';

    if ($user === 'admin' && $pass === 'geheim') {
        // 1 Stunde = 3600 Sekunden
        setcookie('eingeloggt', '1', time() + 3600);
        header('Location: dashboard.php');
        exit; // WICHTIG: Script nach header() sofort beenden!
    } else {
        $fehler = 'Falscher Benutzername oder Passwort.';
    }
}
?>
<!DOCTYPE html><html><body>
<h1>Login</h1>
<?php if ($fehler): ?>
    <p style="color:red"><?= htmlspecialchars($fehler) ?></p>
<?php endif; ?>
<form method="post">
    <input type="text" name="benutzer" placeholder="Benutzername">
    <input type="password" name="passwort" placeholder="Passwort">
    <button type="submit">Einloggen</button>
</form>
</body></html>

dashboard.php

<?php
// Zugriff verweigern, wenn nicht eingeloggt
if (($_COOKIE['eingeloggt'] ?? '') !== '1') {
    header('Location: login.php');
    exit;
}
?>
<!DOCTYPE html><html><body>
<h1>Willkommen im Dashboard!</h1>
<a href="logout.php">Logout</a>
</body></html>

logout.php

<?php
// Cookie löschen: Ablaufzeit in die Vergangenheit setzen
setcookie('eingeloggt', '', time() - 1);
header('Location: login.php');
exit;
Aufgabe 4

Mini-Warenkorb mit JSON

Schwer

Erstelle eine Datei warenkorb.php, die einen einfachen Warenkorb über einen Cookie verwaltet.

  • Drei fest definierte Produkte: Apfel, Banane, Kirsche.
  • Für jedes Produkt gibt es einen „Hinzufügen"-Button (POST-Formular).
  • Die Liste der Artikel im Warenkorb wird als JSON-String in einem Cookie namens warenkorb gespeichert (Gültigkeit: 1 Tag).
  • Die Seite zeigt den aktuellen Warenkorb-Inhalt als Liste an.
  • Ein „Warenkorb leeren"-Button löscht den Cookie.
Schlüsselfunktionen:
  • json_encode($array) → Array in JSON-String umwandeln (zum Speichern)
  • json_decode($string, true) → JSON-String zurück in Array (zum Lesen)
  • Validiere das hinzugefügte Produkt mit in_array() gegen die erlaubten Produkte!
<?php
$erlaubteProdukte = ['Apfel', 'Banane', 'Kirsche'];

// Warenkorb aus Cookie lesen (leeres Array als Fallback)
$korb = [];
if (isset($_COOKIE['warenkorb'])) {
    $decoded = json_decode($_COOKIE['warenkorb'], true);
    if (is_array($decoded)) {
        $korb = $decoded;
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['leeren'])) {
        // Warenkorb leeren: Cookie löschen
        setcookie('warenkorb', '', time() - 1);
        $korb = [];
    } elseif (isset($_POST['produkt'])) {
        $produkt = $_POST['produkt'];
        // Nur erlaubte Produkte hinzufügen!
        if (in_array($produkt, $erlaubteProdukte, true)) {
            $korb[] = $produkt;
            setcookie('warenkorb', json_encode($korb), time() + 86400);
        }
    }
}
?>
<!DOCTYPE html><html><body>
<h1>Mein Warenkorb</h1>

<h2>Produkte</h2>
<?php foreach ($erlaubteProdukte as $p): ?>
    <form method="post" style="display:inline">
        <input type="hidden" name="produkt" value="<?= htmlspecialchars($p) ?>">
        <button><?= htmlspecialchars($p) ?> hinzufügen</button>
    </form>
<?php endforeach; ?>

<h2>Im Korb</h2>
<?php if (empty($korb)): ?>
    <p>Der Warenkorb ist leer.</p>
<?php else: ?>
    <ul>
    <?php foreach ($korb as $artikel): ?>
        <li><?= htmlspecialchars($artikel) ?></li>
    <?php endforeach; ?>
    </ul>
    <form method="post">
        <button name="leeren">Warenkorb leeren</button>
    </form>
<?php endif; ?>
</body></html>
Aufgabe 5

Cookie-Optionen: path, secure, httponly

Herausforderung

Die vollständige Signatur von setcookie() bietet wichtige Sicherheits- und Gültigkeitsoptionen. Verwende in dieser Aufgabe die Array-Schreibweise:

setcookie('name', 'wert', [
    'expires' => time() + 3600, // Ablaufzeit
    'path' => '/', // Gültig für die gesamte Domain
    'secure' => true, // Nur über HTTPS senden
    'httponly' => true, // Kein Zugriff via JavaScript
    'samesite' => 'Lax', // CSRF-Schutz
]);

Beantworte folgende Fragen und implementiere die Lösung:

  • Schreibe eine Datei sicher.php, die einen Cookie token mit einem zufälligen Wert (bin2hex(random_bytes(16))) setzt – mit httponly: true und path: '/'.
  • Warum kann JavaScript diesen Cookie nicht auslesen? Überprüfe es mit der Browser-Konsole: document.cookie.
  • Öffne die Browser-Entwicklertools (F12 → Application → Cookies) und prüfe welche Flags gesetzt sind.
Die drei wichtigsten Sicherheits-Flags im Überblick:
httponly JavaScript kann den Cookie nicht lesen → schützt vor XSS-Angriffen.
secure Cookie wird nur über verschlüsselte HTTPS-Verbindungen übertragen.
samesite Lax oder Strict verhindert, dass Cookies bei Cross-Site-Requests mitgesendet werden → CSRF-Schutz.
<?php
// Zufälligen Token generieren
$token = bin2hex(random_bytes(16)); // 32 zufällige Hex-Zeichen

setcookie('token', $token, [
    'expires' => time() + 3600,
    'path' => '/',
    'secure' => false, // false, da localhost kein HTTPS hat
    'httponly' => true, // JavaScript kann diesen Cookie NICHT lesen
    'samesite' => 'Lax',
]);
?>
<!DOCTYPE html><html><body>
<h1>Sicherer Cookie gesetzt!</h1>
<p>Token (serverseitig): <?= htmlspecialchars($token) ?></p>
<p>Öffne die Konsole und gib <code>document.cookie</code> ein.
Der Token-Cookie sollte dort nicht erscheinen!</p>
</body></html>

In echten Webanwendungen (Session-Cookies, Auth-Tokens) sollten httponly und samesite immer gesetzt sein. secure wird auf dem Live-Server zusätzlich aktiviert, sobald HTTPS verfügbar ist.

Dynamische Webseiten 2 | eduhigh.net | Seminarunterlagen