Website-Login mit HTML: Formular, Backend, Sicherheit
Ein Login-Formular ist in wenigen Minuten geschrieben – die eigentliche Arbeit steckt in dem, was dahinter passiert. Reines HTML zeigt Eingabefelder an, meldet aber niemanden an: Es prüft keine Passwörter, merkt sich keinen angemeldeten Zustand und schützt keine Inhalte. Hier bekommen Sie das saubere HTML-Formular, die Anbindung an ein PHP-Backend und die Sicherheitsmaßnahmen, die kein produktiver Login auslassen darf. Am Ende bauen Sie ein funktionierendes Anmeldesystem selbst – oder entscheiden bewusst, eine fertige Lösung zu nutzen.
Was HTML beim Login leistet – und was nicht
HTML liefert ausschließlich die Struktur des Formulars: die Felder, in die Nutzer E-Mail und Passwort eintippen, und den Absende-Button. Die Prüfung „Stimmt dieses Passwort?”, das Merken des angemeldeten Zustands und das Absichern geschützter Seiten passieren auf dem Server – nicht im Browser.
Wichtig zum Verständnis: Ein Login lässt sich nicht allein mit HTML und auch nicht allein mit clientseitigem JavaScript absichern. Alles, was im Browser läuft, kann jeder Besucher im Quelltext lesen und verändern. Die Zugangskontrolle gehört deshalb immer serverseitig – etwa in PHP, Node.js oder Python – zusammen mit einer Datenbank und einer Session-Verwaltung.
Das Login-Formular in HTML
So sieht ein sauberes, barrierefreies Login-Formular aus:
<form action="/login" method="post" class="login-form">
<label for="email">E-Mail</label>
<input type="email" id="email" name="email"
autocomplete="username" required>
<label for="password">Passwort</label>
<input type="password" id="password" name="password"
autocomplete="current-password" required minlength="8">
<button type="submit">Anmelden</button>
</form>
Warum diese Attribute wichtig sind
method="post"– niemalsget. Bei GET landet das Passwort in der URL, im Browserverlauf und in den Server-Logs.type="email"/type="password"– blenden das Passwort aus und zeigen auf dem Smartphone die passende Tastatur.autocomplete="username"und"current-password"– erst dadurch erkennen Browser und Passwortmanager die Felder zuverlässig und bieten Speichern und Ausfüllen an.required/minlength– prüfen die Eingabe schon im Browser. Das ist reiner Bedienkomfort, keine Sicherheit: Diese Prüfung müssen Sie auf dem Server wiederholen.labelmitfor/id– verknüpft Beschriftung und Feld, wichtig für Screenreader und größere Klickflächen.
Der Wert von action muss auf eine HTTPS-Adresse zeigen. Ohne TLS-Verschlüsselung überträgt das Formular E-Mail-Adresse und Passwort im Klartext – jeder im selben WLAN oder auf der Übertragungsstrecke kann mitlesen.
Vom Formular zum echten Login: das Backend
Damit ein Login funktioniert, brauchen Sie zwei Dinge: eine Registrierung, die das Passwort als Hash speichert, und eine Anmeldung, die die Eingabe gegen diesen Hash prüft. Die folgenden Beispiele nutzen PHP mit PDO und vorbereiteten Anweisungen (Prepared Statements).
Bei der Registrierung wird das Passwort niemals im Klartext gespeichert, sondern über password_hash() in einen nicht umkehrbaren Hash umgewandelt:
<?php
// register.php – Ausschnitt
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$password = $_POST['password'] ?? '';
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare(
'INSERT INTO users (email, password_hash) VALUES (?, ?)'
);
$stmt->execute([$email, $hash]);
Bei der Anmeldung vergleicht password_verify() die Eingabe mit dem gespeicherten Hash:
<?php
// login.php – Ausschnitt
session_start();
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password_hash'])) {
session_regenerate_id(true); // schützt vor Session-Fixation
$_SESSION['user_id'] = $user['id'];
header('Location: /dashboard.php');
exit; // nach header() zwingend beenden
}
// Bewusst dieselbe Meldung für „E-Mail unbekannt" und „Passwort falsch"
$error = 'E-Mail oder Passwort ist falsch.';
Ein paar Details, die oft übersehen werden:
password_hash()verwendet mitPASSWORD_DEFAULTaktuell bcrypt. Wer Argon2id bevorzugt, nutztPASSWORD_ARGON2ID(ab PHP 7.3). Der Standard darf sich in künftigen PHP-Versionen ändern – deshalb sollte die Datenbankspalte großzügig dimensioniert sein (mindestensVARCHAR(255)).- Prepared Statements (die
?-Platzhalter) verhindern SQL-Injection. Setzen Sie Nutzereingaben nie direkt in einen SQL-String ein. - Die gleiche Fehlermeldung für beide Fälle verhindert „User Enumeration” – also dass Angreifer herausfinden, welche E-Mail-Adressen registriert sind.
session_regenerate_id(true)nach erfolgreicher Anmeldung und dasexitnachheader('Location: …')sind Pflicht, keine Kür.
Sicherheit: die Pflichtmaßnahmen
Ein Login verarbeitet die sensibelsten Daten Ihrer Seite. Diese Punkte sind nicht optional:
- HTTPS erzwingen. Ohne TLS ist jede Anmeldung abhörbar. Leiten Sie HTTP dauerhaft per 301 auf HTTPS um.
- Passwörter hashen, nie im Klartext, MD5 oder SHA1 speichern.
- Prepared Statements gegen SQL-Injection.
- Brute-Force-Schutz: Anmeldeversuche pro Konto und IP begrenzen, nach mehreren Fehlversuchen verzögern oder ein CAPTCHA verlangen.
- CSRF-Token in jedes Formular einbauen und serverseitig prüfen – sonst kann eine fremde Seite Formulare in Ihrem Namen absenden:
// Formularseite: Token erzeugen und ausgeben
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
<input type="hidden" name="csrf_token"
value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
// login.php: Token vor der eigentlichen Prüfung verifizieren
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf_token'] ?? '')) {
http_response_code(403);
exit('Ungültige Anfrage.');
}
- Sichere Session-Cookies setzen:
session_set_cookie_params([
'httponly' => true, // kein Zugriff per JavaScript
'secure' => true, // nur über HTTPS senden
'samesite' => 'Lax',
]);
session_start();
- Serverseitig validieren. Die HTML-Attribute
requiredundminlengthsind nur Komfort und lassen sich umgehen.
Sobald Sie E-Mail-Adressen oder Namen speichern, verarbeiten Sie personenbezogene Daten und damit greift die DSGVO – von der Rechtsgrundlage über die Datenschutzerklärung bis zur Löschfrist. Einen Überblick, worauf Dienste dabei achten müssen, finden Sie unter welche Apps DSGVO-konform sind.
Wann Sie besser keinen eigenen Login bauen
Für die meisten Websites lohnt sich der Eigenbau nicht. Ein selbst geschriebenes Anmeldesystem muss Passwort-Reset, 2-Faktor-Authentifizierung, Brute-Force-Schutz und Session-Handling dauerhaft sicher halten – das ist Wartungsarbeit. Sinnvolle Alternativen:
- Content-Management-Systeme: WordPress, Typo3 & Co. bringen einen erprobten Login mit. Wenn Sie ohnehin eine Website erstellen, nutzen Sie den vorhandenen Mechanismus.
- Authentifizierungs-Dienste: Auth0, Clerk, Supabase Auth, Firebase Auth oder das selbst gehostete Keycloak übernehmen Hashing, 2FA und Passwort-Reset für Sie.
- Einfacher Passwortschutz für einen Bereich: Wenn nur ein Verzeichnis geschützt werden soll und Sie keine echten Nutzerkonten brauchen, genügt auf Apache-Servern die HTTP-Basisauthentifizierung per
.htaccess:
# .htaccess
AuthType Basic
AuthName "Geschützter Bereich"
AuthUserFile /pfad/zu/.htpasswd
Require valid-user
Die zugehörige .htpasswd-Datei legen Sie mit htpasswd -c /pfad/zu/.htpasswd benutzername an. Das genügt für einen internen Vorschau-Bereich, ersetzt aber keinen richtigen Login mit Nutzerkonten.
Häufige Fehler
- Passwortprüfung im JavaScript – jeder sieht den Quelltext und umgeht sie. Mehr zu den Grenzen von Clientcode lesen Sie unter hat JavaScript Zukunft.
method="get"stattpost– das Passwort landet in URL, Verlauf und Logs.- Passwörter im Klartext oder als MD5/SHA1 gespeichert.
- Zu gesprächige Fehlermeldungen wie „Diese E-Mail existiert nicht” – sie verraten gültige Konten.
- Fehlendes
exitnach der Weiterleitung – der restliche Code läuft weiter und kann geschützte Daten ausgeben.
FAQ
Kann man einen Login nur mit HTML erstellen? Nein. HTML liefert ausschließlich das Formular. Zum Prüfen der Zugangsdaten, Merken des Anmeldestatus und Schützen von Inhalten brauchen Sie serverseitigen Code (z. B. PHP, Node.js oder Python) plus Datenbank und Session-Verwaltung.
Reicht JavaScript, um einen Login abzusichern? Nein. Clientseitiges JavaScript ist im Browser einsehbar und manipulierbar. Es eignet sich für Komfort wie Live-Validierung, niemals als alleinige Zugangskontrolle. Die entscheidende Prüfung muss auf dem Server stattfinden.
Wie speichere ich Passwörter richtig?
Mit einer Hash-Funktion wie password_hash() (Standard bcrypt, optional Argon2id). Gespeichert wird nur der Hash. Beim Login vergleicht password_verify() die Eingabe mit dem Hash. Klartext, MD5 und SHA1 sind tabu.