Skip to content

Kapitel 10: Session-Control (Login-Status)

Was sind Cookies?

Cookies sind kleine Textdateien, die auf dem Computer des Benutzers gespeichert werden.

php
<?php
    // Cookie setzen (muss vor HTML-Ausgabe gemacht werden!)
    setcookie("benutzer", "Max", time() + 3600);  // 1 Stunde gültig
    setcookie("alter", "25", time() + 86400, "/");  // 1 Tag, für ganze Domain
    
    // Cookie auslesen
    $benutzer = $_COOKIE['benutzer'] ?? 'Gast';
    echo "Willkommen " . $benutzer;
    
    // Cookie löschen
    setcookie("benutzer", "", time() - 3600);  // Zeit in Vergangenheit setzen
?>

<!-- 
Cookie-Parameter (setcookie):
1. Name des Cookies
2. Wert des Cookies
3. Ablaufzeit (Unix-Timestamp)
4. Pfad (Standard: aktuelles Verzeichnis)
5. Domain (Standard: aktuelle Domain)
6. Secure (nur über HTTPS senden)
7. HttpOnly (nicht über JavaScript zugreifbar - XSS-Schutz)
-->
php
<?php
    // login_cookie.php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $benutzer = $_POST['benutzer'] ?? '';
        $passwort = $_POST['passwort'] ?? '';
        $angemeldet_bleiben = isset($_POST['angemeldet_bleiben']);
        
        // "Login" prüfen (Beispiel)
        if ($benutzer === "max" && $passwort === "geheim") {
            if ($angemeldet_bleiben) {
                // Cookie für 30 Tage setzen
                setcookie("benutzer", $benutzer, time() + 60*60*24*30, "/", "", false, true);
                setcookie("token", "irgendein_token", time() + 60*60*24*30, "/", "", false, true);
            } else {
                // Session-Cookie (verschwindet beim Browser-Schliessen)
                setcookie("benutzer", $benutzer, 0, "/", "", false, true);
            }
            
            header("Location: willkommen.php");
            exit();
        } else {
            $fehler = "Benutzername oder Passwort falsch.";
        }
    }
?>

<!-- 
Wichtige Cookie-Einstellungen:
- Secure: true (nur über HTTPS senden - Produktion!)
- HttpOnly: true (XSS-Schutz - JavaScript kann Cookie nicht lesen)
- SameSite: Strict (CSRF-Schutz)
-->

10.2 Session-Prinzip und Verwendung

Was ist eine Session?

Eine Session speichert Daten serverseitig (im Gegensatz zu Cookies, die clientseitig gespeichert werden).

php
<?php
    // Session starten (muss vor jeglicher Ausgabe stehen!)
    session_start();
    
    // Session-Variable setzen
    $_SESSION['benutzer'] = "Max";
    $_SESSION['eingeloggt'] = true;
    $_SESSION['alter'] = 25;
    
    // Session-Variable auslesen
    $benutzer = $_SESSION['benutzer'] ?? 'Gast';
    echo "Willkommen " . $benutzer;
    
    // Session-Variable löschen
    unset($_SESSION['alter']);
    
    // Alle Session-Variablen löschen (aber Session bleibt bestehen)
    session_unset();
    
    // Session komplett zerstören (inkl. Session-Cookie)
    session_destroy();
?>

<!-- 
Wie funktioniert Session?
1. session_start() erzeugt eine eindeutige Session-ID
2. Diese ID wird als Session-Cookie an den Browser gesendet
3. Bei jedem weiteren Request sendet der Browser die Session-ID
4. PHP findet die dazugehörigen Session-Daten auf dem Server
-->

Session-Konfiguration (php.ini)

ini
; Einstellungen für Sessions
session.save_handler = files       ; Sessions in Dateien speichern
session.save_path = "C:\xampp\tmp"  ; Pfad für Session-Dateien
session.use_cookies = 1            ; Cookies verwenden
session.use_only_cookies = 1        ; Nur Cookies (Sicherheit)
session.auto_start = 0              ; Session nicht automatisch starten
session.cookie_lifetime = 0         ; 0 = bis Browser geschlossen
session.cookie_secure = 1           ; Nur HTTPS (Produktion!)
session.cookie_httponly = 1         ; XSS-Schutz
session.use_strict_mode = 1          ; Strenge Session-ID-Prüfung
session.gc_maxlifetime = 1440        ; Session-Gültigkeit (Sekunden)

10.3 Login- und Logout-Logik

Login-Logik

php
<?php
    // login_session.php
    session_start();
    
    // Wenn bereits eingeloggt: Weiterleiten
    if (isset($_SESSION['eingeloggt']) && $_SESSION['eingeloggt'] === true) {
        header("Location: willkommen.php");
        exit();
    }
    
    $fehler = [];
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $benutzer = trim($_POST['benutzer'] ?? '');
        $passwort = $_POST['passwort'] ?? '';
        
        // Validierung
        if (empty($benutzer)) {
            $fehler[] = "Benutzername darf nicht leer sein.";
        }
        if (empty($passwort)) {
            $fehler[] = "Passwort darf nicht leer sein.";
        }
        
        // Login prüfen (Beispiel - in echtem Projekt: Datenbank!)
        if (empty($fehler)) {
            // Beispiel-Benutzer (in echt: aus Datenbank)
            $benutzer_korrekt = "max";
            $passwort_hash = password_hash("geheim", PASSWORD_DEFAULT);
            
            if ($benutzer === $benutzer_korrekt && password_verify($passwort, $passwort_hash)) {
                // Login erfolgreich: Session-Variablen setzen
                $_SESSION['benutzer'] = $benutzer;
                $_SESSION['eingeloggt'] = true;
                $_SESSION['login_zeit'] = time();
                
                // Regenerate Session-ID (Sicherheitsmassnahme gegen Session-Fixation)
                session_regenerate_id(true);
                
                header("Location: willkommen.php");
                exit();
            } else {
                $fehler[] = "Benutzername oder Passwort falsch.";
            }
        }
    }
?>

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    
    <?php if (!empty($fehler)): ?>
        <div style="color: red;">
            <ul>
                <?php foreach ($fehler as $f): ?>
                    <li><?php echo htmlspecialchars($f); ?></li>
                <?php endforeach; ?>
            </ul>
        </div>
    <?php endif; ?>
    
    <form method="post">
        <label>Benutzername:<br>
            <input type="text" name="benutzer" required>
        </label><br><br>
        
        <label>Passwort:<br>
            <input type="password" name="passwort" required>
        </label><br><br>
        
        <button type="submit">Einloggen</button>
    </form>
</body>
</html>

Logout-Logik

php
<?php
    // logout.php
    session_start();
    
    // Session-Variablen löschen
    $_SESSION = array();
    
    // Session-Cookie löschen
    if (ini_get("session.use_cookies")) {
        $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000,
            $params["path"], $params["domain"],
            $params["secure"], $params["httponly"]
        );
    }
    
    // Session zerstören
    session_destroy();
    
    // Zur Login-Seite weiterleiten
    header("Location: login_session.php");
    exit();
?>

10.4 Login-Status prüfen

Login-Status in geschützten Seiten prüfen

php
<?php
    // geschuetzte_seite.php
    session_start();
    
    // Prüfen, ob Benutzer eingeloggt ist
    if (!isset($_SESSION['eingeloggt']) || $_SESSION['eingeloggt'] !== true) {
        // Nicht eingeloggt: Zur Login-Seite weiterleiten
        header("Location: login_session.php");
        exit();
    }
    
    // Benutzer ist eingeloggt
    $benutzer = $_SESSION['benutzer'];
    $login_zeit = $_SESSION['login_zeit'];
    $login_dauer = time() - $login_zeit;
?>

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Geschützte Seite</title>
</head>
<body>
    <h2>Willkommen, <?php echo htmlspecialchars($benutzer); ?>!</h2>
    <p>Sie sind seit <?php echo gmdate("H:i:s", $login_dauer); ?> eingeloggt.</p>
    
    <p><a href="willkommen.php">Zur Startseite</a></p>
    <p><a href="logout.php">Ausloggen</a></p>
</body>
</html>

Automatische Login-Prüfung (für alle geschützten Seiten)

php
<?php
    // auth_check.php (Datei, die am Anfang jeder geschützten Seite inkludiert wird)
    session_start();
    
    function pruefeLoginStatus() {
        if (!isset($_SESSION['eingeloggt']) || $_SESSION['eingeloggt'] !== true) {
            // Nicht eingeloggt: Zur Login-Seite weiterleiten
            header("Location: login_session.php");
            exit();
        }
    }
    
    function aktuellerBenutzer() {
        return $_SESSION['benutzer'] ?? null;
    }
    
    function istEingeloggt() {
        return isset($_SESSION['eingeloggt']) && $_SESSION['eingeloggt'] === true;
    }
    
    function logout() {
        $_SESSION = array();
        
        if (ini_get("session.use_cookies")) {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() - 42000,
                $params["path"], $params["domain"],
                $params["secure"], $params["httponly"]
            );
        }
        
        session_destroy();
    }
?>

<!-- 
Verwendung in geschützten Seiten:
<?php
    require_once 'auth_check.php';
    pruefeLoginStatus();
    
    // Benutzer ist eingeloggt
    $benutzer = aktuellerBenutzer();
?>
-->

10.5 Praxis: Benutzer-Login-System

Vollständiges Login-System (Beispiel)

php
<?php
    // config.php (Datenbank-Konfiguration)
    define('DB_HOST', 'localhost');
    define('DB_USER', 'root');
    define('DB_PASS', '');
    define('DB_NAME', 'meine_datenbank');
    
    // Datenbankverbindung herstellen
    function db_connect() {
        $conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        
        if ($conn->connect_error) {
            die("Verbindungsfehler: " . $conn->connect_error);
        }
        
        $conn->set_charset("utf8");
        return $conn;
    }
?>

<?php
    // register.php (Registrierung)
    session_start();
    require_once 'config.php';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $benutzer = trim($_POST['benutzer'] ?? '');
        $email = trim($_POST['email'] ?? '');
        $passwort = $_POST['passwort'] ?? '';
        $passwort_bestätigen = $_POST['passwort_bestätigen'] ?? '';
        
        $fehler = [];
        
        // Validierung (wie in Kapitel 9)
        if (empty($benutzer) || strlen($benutzer) < 3) {
            $fehler[] = "Benutzername muss mindestens 3 Zeichen lang sein.";
        }
        
        if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $fehler[] = "Gültige E-Mail-Adresse erforderlich.";
        }
        
        if (empty($passwort) || strlen($passwort) < 8) {
            $fehler[] = "Passwort muss mindestens 8 Zeichen lang sein.";
        }
        
        if ($passwort !== $passwort_bestätigen) {
            $fehler[] = "Passwörter stimmen nicht überein.";
        }
        
        // Wenn keine Fehler: In Datenbank speichern
        if (empty($fehler)) {
            $conn = db_connect();
            
            // Prüfen, ob Benutzername oder E-Mail bereits existiert
            $stmt = $conn->prepare("SELECT id FROM benutzer WHERE benutzer = ? OR email = ?");
            $stmt->bind_param("ss", $benutzer, $email);
            $stmt->execute();
            $stmt->store_result();
            
            if ($stmt->num_rows > 0) {
                $fehler[] = "Benutzername oder E-Mail bereits registriert.";
            } else {
                // Benutzer speichern
                $passwort_hash = password_hash($passwort, PASSWORD_DEFAULT);
                $stmt = $conn->prepare("INSERT INTO benutzer (benutzer, email, passwort) VALUES (?, ?, ?)");
                $stmt->bind_param("sss", $benutzer, $email, $passwort_hash);
                
                if ($stmt->execute()) {
                    $_SESSION['registrierung_erfolgreich'] = true;
                    header("Location: login.php");
                    exit();
                } else {
                    $fehler[] = "Fehler bei der Registrierung.";
                }
            }
            
            $stmt->close();
            $conn->close();
        }
    }
?>

<?php
    // login.php (Login)
    session_start();
    require_once 'config.php';
    
    if (isset($_SESSION['eingeloggt']) && $_SESSION['eingeloggt'] === true) {
        header("Location: dashboard.php");
        exit();
    }
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $benutzer = trim($_POST['benutzer'] ?? '');
        $passwort = $_POST['passwort'] ?? '';
        
        $fehler = [];
        
        if (empty($benutzer)) {
            $fehler[] = "Benutzername darf nicht leer sein.";
        }
        if (empty($passwort)) {
            $fehler[] = "Passwort darf nicht leer sein.";
        }
        
        if (empty($fehler)) {
            $conn = db_connect();
            
            $stmt = $conn->prepare("SELECT id, benutzer, passwort FROM benutzer WHERE benutzer = ?");
            $stmt->bind_param("s", $benutzer);
            $stmt->execute();
            $stmt->store_result();
            
            if ($stmt->num_rows === 1) {
                $stmt->bind_result($id, $benutzer_db, $passwort_hash);
                $stmt->fetch();
                
                if (password_verify($passwort, $passwort_hash)) {
                    // Login erfolgreich
                    session_regenerate_id(true);
                    
                    $_SESSION['benutzer_id'] = $id;
                    $_SESSION['benutzer'] = $benutzer_db;
                    $_SESSION['eingeloggt'] = true;
                    
                    header("Location: dashboard.php");
                    exit();
                } else {
                    $fehler[] = "Benutzername oder Passwort falsch.";
                }
            } else {
                $fehler[] = "Benutzername oder Passwort falsch.";
            }
            
            $stmt->close();
            $conn->close();
        }
    }
?>

<?php
    // dashboard.php (Geschützte Seite)
    session_start();
    
    if (!isset($_SESSION['eingeloggt']) || $_SESSION['eingeloggt'] !== true) {
        header("Location: login.php");
        exit();
    }
?>

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
</head>
<body>
    <h2>Willkommen, <?php echo htmlspecialchars($_SESSION['benutzer']); ?>!</h2>
    <p>Dies ist eine geschützte Seite.</p>
    
    <p><a href="logout.php">Ausloggen</a></p>
</body>
</html>

Zusammenfassung

In diesem Kapitel haben Sie:

  • ✅ Das Cookie-Prinzip verstanden und Cookies verwendet
  • ✅ Das Session-Prinzip verstanden und Sessions verwendet
  • ✅ Login- und Logout-Logik implementiert
  • ✅ Login-Status in geschützten Seiten geprüft
  • ✅ Ein vollständiges Benutzer-Login-System erstellt

Nächstes Kapitel: Wir werden Datenbank-Grundlagen lernen (MySQL).


Übungsaufgaben:

  1. Erstellen Sie ein Login-System mit Session-Verwaltung
  2. Implementieren Sie "Angemeldet bleiben" mit Cookies
  3. Erstellen Sie eine Registrierungsseite mit Datenbankanbindung
  4. Schützen Sie Seiten vor unbefugtem Zugriff

Häufige Fehler:

  • session_start() nach HTML-Ausgabe aufrufen → Muss ganz am Anfang stehen!
  • ❌ Session-Daten in URLs übertragen → Sicherheitsrisiko!
  • session_destroy() ohne Cookie-Löschung → Session-Cookie bleibt bestehen!
  • ❌ Keine Session-ID-Regenerierung nach Login → Session-Fixation-Angriff!

Frei für alle Anfänger