Kapitel 4
login.php – Einloggen
Sehr ähnlich zu register: Formular → beim Absenden User aus DB holen → Passwort mit password_verify() prüfen → bei Erfolg Session setzen und weiterleiten.
Der Code
login.php
<?php
require_once('db.php');
session_start();
$fehler = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if ($username === '' || $password === '') {
$fehler = 'Bitte alle Felder ausfüllen.';
} else {
// user aus db holen
$stmt = $conn->prepare("SELECT id, username, email, password_hash, rolle FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
// passwort prüfen
if ($user && password_verify($password, $user['password_hash'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['rolle'] = $user['rolle'];
header('Location: index.php');
exit;
} else {
$fehler = 'Benutzername oder Passwort falsch!';
}
}
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<?php include('navbar.php'); ?>
<h1>Login</h1>
<?php if ($fehler !== ''): ?>
<p style="color: red;"><?= htmlspecialchars($fehler, ENT_QUOTES, 'UTF-8') ?></p>
<?php endif; ?>
<form action="login.php" method="POST">
<label>Benutzername:<br>
<input type="text" name="username" required>
</label><br><br>
<label>Passwort:<br>
<input type="password" name="password" required>
</label><br><br>
<button type="submit">Einloggen</button>
</form>
</body>
</html>
Was passiert Schritt für Schritt
- User-Datensatz per Prepared Statement holen (Prevention SQL Injection).
- password_verify(input, hash) – vergleicht das eingetippte Passwort mit dem Hash aus der DB. Das Passwort wird nicht entschlüsselt (Hashes sind Einweg), sondern bcrypt hasht die Eingabe mit dem gleichen Salt und vergleicht.
- Bei Erfolg: alle relevanten Userdaten in die Session (id, username, email, rolle). Die
rollebraucht die navbar für den Admin-Menüpunkt. - Bei Fehler: bewusst unspezifische Meldung "Benutzername ODER Passwort falsch". Man verrät nicht, ob der Username existiert (sonst User Enumeration).
Prüfer-Frage: "Warum kein
SELECT * FROM users?" → Nur die Spalten holen, die man wirklich braucht. Weniger Datentransfer, weniger versehentlicher Leak sensibler Daten.