Modul 295


Backend für Applikationen realisieren

Web Icon

07 - Sessions


Zustand über mehrere Requests hinweg

PHP Logo

Lernziele dieser Lektion

  • Erklären können, wieso HTTP zustandslos ist und welches Problem Sessions lösen
  • Eine Session mit session_start() starten und mit $_SESSION Daten speichern/lesen können
  • Den Zusammenhang zwischen Session-ID, Cookie und serverseitiger Speicherung erklären können
  • Einen einfachen Login-Mechanismus mit Sessions umsetzen können
  • Sessions sauber beenden (session_destroy(), unset()) und sich der wichtigsten Sicherheitsaspekte bewusst sein

Rückblick: Klassen

  • Mit Klassen haben wir Daten (Eigenschaften) und Verhalten (Methoden) in Objekten gebündelt
  • Ein Objekt lebt aber nur so lange wie das PHP-Skript läuft - danach ist es weg
  • Heute: Wie können Daten über mehrere Seitenaufrufe hinweg erhalten bleiben?

HTTP ist zustandslos

  • Jeder Request des Browsers an den Server ist unabhängig - der Server "erinnert" sich standardmässig nicht an vorherige Requests
  • Variablen eines Skripts existieren nur für die Dauer dieses einen Requests - danach sind sie weg
  • Ohne Zusatzmechanismus würde z.B. ein Login-Status bei jedem neuen Seitenaufruf verloren gehen
                    
                        <?php
                        $loggedIn = true; // gilt nur für diesen einen Request
                        // Beim nächsten Aufruf der Seite ist $loggedIn wieder weg
                    
                

Wozu Sessions?

  • Eine Session erlaubt es, Daten für einen bestimmten Besucher über mehrere Seitenaufrufe hinweg zu speichern
  • Typische Anwendungen: Login-Status, Warenkorb, Spracheinstellung, Formular-Zwischenspeicherung
  • Die Daten werden dazu serverseitig abgelegt - der Browser merkt sich nur einen "Schlüssel" dazu

Cookies als Grundlage

  • Damit der Server einen Besucher bei einem erneuten Request wiedererkennt, schickt er beim ersten Besuch ein Cookie mit einer eindeutigen ID an den Browser
  • Der Browser sendet dieses Cookie bei jedem weiteren Request automatisch mit - so weiss der Server, "wer" anfragt
  • PHP übernimmt diesen Mechanismus automatisch, sobald man Sessions verwendet

session_start()

  • Jedes Skript, das mit Sessions arbeitet, muss zu Beginn session_start() aufrufen
  • Startet eine neue Session oder setzt (anhand des Cookies) eine bestehende fort
  • Wichtig: muss aufgerufen werden, bevor irgendeine Ausgabe (echo, HTML) gesendet wird
                    
                        <?php
                        session_start();
                        // ab hier steht $_SESSION zur Verfügung
                        ?>
                        <!DOCTYPE html>
                        ...
                    
                

Die Session-ID

  • session_start() erzeugt beim ersten Aufruf eine zufällige, eindeutige Session-ID und schickt sie im Cookie PHPSESSID an den Browser
  • Bei jedem weiteren Request desselben Browsers wird diese ID mitgeschickt - PHP findet damit die passenden Daten auf dem Server wieder
                    
                        <?php
                        session_start();
                        echo session_id(); // z.B. "8f3ac9d2e1b4..."
                    
                

$_SESSION - Werte speichern

  • $_SESSION ist ein superglobales Array - wie $_GET, aber von PHP serverseitig verwaltet
  • Werte werden ganz normal wie bei einem Array zugewiesen
                    
                        <?php
                        session_start();
                        $_SESSION["username"] = "Anna";
                        $_SESSION["views"] = 1;
                    
                

$_SESSION - Werte lesen

  • Beim nächsten Aufruf derselben Seite (z.B. durch Neuladen) sind die zuvor gespeicherten Werte immer noch da
                    
                        <?php
                        session_start();
                        echo $_SESSION["username"] ?? "Unbekannt";
                        // "Anna" - auch nach dem Neuladen der Seite
                    
                

Beispiel: Seitenaufrufe zählen

  • Praktisches Beispiel, bei dem man die Wirkung von Sessions direkt sieht: Seite mehrmals neu laden (F5)
                    
                        <?php
                        session_start();
                        $_SESSION["views"] = ($_SESSION["views"] ?? 0) + 1;
                        echo "Sie haben diese Seite " . $_SESSION["views"] . " Mal aufgerufen";
                        // 1, 2, 3, ... bei jedem Neuladen
                    
                

Wo werden Session-Daten gespeichert?

  • Die eigentlichen Daten liegen auf dem Server (standardmässig in Dateien) - nicht im Cookie
  • Im Cookie steht nur die Session-ID, ein Verweis auf die Daten
  • Vorteil: grosse oder sensible Daten müssen nicht zum Client übertragen werden

Session-Variable prüfen mit isset()

  • Vor dem Zugriff auf eine Session-Variable prüft man meist mit isset(), ob sie existiert
  • Sonst löst der Zugriff eine Warnung aus, falls die Variable (noch) nicht gesetzt ist
                    
                        <?php
                        session_start();
                        if (isset($_SESSION["username"])) {
                            echo "Eingeloggt als " . $_SESSION["username"];
                        } else {
                            echo "Nicht eingeloggt";
                        }
                    
                

Praxisbeispiel: Login

  • Login-Status ist der klassische Anwendungsfall für Sessions
  • Echte Formulare folgen erst in einer späteren Lektion - hier simulieren wir die Eingabe über URL-Parameter ($_GET)
                    
                        <?php
                        session_start();
                        // Aufruf z.B. mit index.php?user=admin&pass=geheim
                        if (($_GET["user"] ?? "") === "admin" && ($_GET["pass"] ?? "") === "geheim") {
                            $_SESSION["username"] = "admin";
                        }
                    
                

Geschützte Seite

  • Mit isset($_SESSION["username"]) lässt sich prüfen, ob jemand eingeloggt ist, und der Inhalt entsprechend anzeigen
                    
                        <?php
                        session_start();
                        if (isset($_SESSION["username"])) {
                            echo "Willkommen, " . $_SESSION["username"] . "!";
                        } else {
                            echo "Bitte zuerst einloggen: index.php?user=admin&pass=geheim";
                        }
                    
                

Logout mit session_destroy()

  • session_destroy() löscht alle Daten der aktuellen Session auf dem Server
  • session_start() muss davor trotzdem aufgerufen werden, damit PHP weiss, welche Session gemeint ist
                    
                        <?php
                        session_start();
                        session_destroy();
                        // $_SESSION ist im aktuellen Skript zwar noch gefüllt,
                        // die Daten sind aber serverseitig bereits gelöscht
                    
                

Einzelne Werte entfernen mit unset()

  • Um nicht die ganze Session, sondern nur einen einzelnen Wert zu löschen, verwendet man unset() - wie bei einem normalen Array
                    
                        <?php
                        session_start();
                        unset($_SESSION["username"]); // nur der Login-Status wird entfernt
                        // andere Session-Daten (z.B. Warenkorb) bleiben erhalten
                    
                

Sicherheit: Session-Fixation

  • Bei einer Session-Fixation-Attacke schiebt ein Angreifer einem Opfer eine ihm bereits bekannte Session-ID unter
  • Gefährlich vor allem rund um den Login: wechselt die ID beim Login nicht, könnte der Angreifer danach dieselbe - jetzt eingeloggte - Session verwenden

TL;DR

  • HTTP ist zustandslos - Sessions erlauben es, Daten serverseitig über mehrere Requests hinweg für einen Besucher zu speichern
  • session_start() startet/setzt eine Session fort; die Verbindung läuft über ein Cookie mit der Session-ID
  • $_SESSION ist ein superglobales Array zum Lesen/Schreiben; isset() prüft auf Existenz, unset() entfernt einzelne Werte
  • session_destroy() beendet eine Session vollständig (z.B. beim Logout)
  • session_regenerate_id() nach dem Login schützt vor Session-Fixation