PHP-Einfach.de
  • PHP Tutorial
  • MySQL Tutorial
  • Für Fortgeschrittene
  • Webhosting
  • Forum

Passwort vergessen

8. Januar 2018
  1. Home
  2. »
  3. Für Fortgeschrittene
  4. »
  5. Script-Beispiele
  6. »
  7. Loginscript
  8. »
  9. Passwort vergessen

Dieser Artikel beschreibt, wie ihr für euren Loginscript eine Passwort vergessen Funktion implementiert.

Der Loginscript funktioniert so, dass an den Benutzer eine E-Mail mit einem Link und einem zufällig erzeugten Code gesendet wird. Ruft der User diesen Link auf, dann hat dieser die Möglichkeit ein neues Passwort zu vergeben. Ihr solltet niemals ein Passwort per E-Mail an den Nutzer senden, weder sein bestehendes Passwort noch ein neu generiertes Passwort, da die Übertragung von E-Mails sehr unsicher ist. Mehr Informationen wie man Passwörter sicher speichern sollte findet ihr im Artikel Passwörter sicher speichern und allgemeine Sicherheitstipp für eine sichere Authentifizierung im Artikel Authentifizierung in PHP.

Das komplette Login-Script könnt ihr hier herunterladen.

Inhaltsverzeichnis

  • 1 Datenbankstruktur
  • 2 PHP-Dateien
    • 2.1 Passwort Vergessen Seite
    • 2.2 Neues Passwort Vergeben

Datenbankstruktur

Um die Passwort-Vergessen-Funktion für den Loginscript implementieren zu können, müssen wir die users-Tabelle um zwei Felder erweitern. Ein Feld für den geheimen Code sowie ein Feld wann dieser Code angefordert wurde. Nur wenn der Code nicht älter als 24 Stunden ist, kann der Benutzer sein Passwort mit dem Code verändern.

Mittels phpMyAdmin könnt ihr für die users-Tabelle zwei neue Spalten hinzufügen:

phpMyAdmin Passwort Code

Der entsprechende SQL-Code zur Erstellung dieser Spalten ist:

1
2
ALTER TABLE `users` ADD `passwortcode` VARCHAR(255) NULL;
ALTER TABLE `users` ADD `passwortcode_time` TIMESTAMP NULL;

In der Spalte passwortcode wird später der notwendige Code gespeichert, in der Spalte passwordcode_time der Zeitpunkt wann dieser Code angefordert wurde. Wichtig ist, dass ihr für beide Spalten den Null-Wert erlaubt.

PHP-Dateien

Für die Passwort-Vergessen-Funktion brauchen wir zwei PHP-Dateien, beispielsweise passwortvergessen.php und passwortzuruecksetzen.php.

Sollte der Benutzer sein Passwort vergessen haben, so kann er mittels Link den ihr in das Login-Formular einbaut die passwortvergessen.php Seite aufrufen. Nach der Eingabe seiner E-Mail-Adresse erhält der Benutzer einen Link zur passwortzuruecksetzen.php. Dort kann er ein neues Passwort vergeben.

Passwort Vergessen Seite

Nachfolgend die Seite, damit ein Benutzer ein neues Passwort anfordern kann (passwortvergessen.php).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'passwort');
 
function random_string() {
if(function_exists('random_bytes')) {
$bytes = random_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes(16);
$str = bin2hex($bytes);
} else if(function_exists('mcrypt_create_iv')) {
$bytes = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$str = bin2hex($bytes);
} else {
//Bitte euer_geheim_string durch einen zufälligen String mit >12 Zeichen austauschen
$str = md5(uniqid('euer_geheimer_string', true));
}
return $str;
}
 
 
$showForm = true;
 
if(isset($_GET['send']) ) {
if(!isset($_POST['email']) || empty($_POST['email'])) {
$error = "<b>Bitte eine E-Mail-Adresse eintragen</b>";
} else {
$statement = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$result = $statement->execute(array('email' => $_POST['email']));
$user = $statement->fetch();
 
if($user === false) {
$error = "<b>Kein Benutzer gefunden</b>";
} else {
//Überprüfe, ob der User schon einen Passwortcode hat oder ob dieser abgelaufen ist
$passwortcode = random_string();
$statement = $pdo->prepare("UPDATE users SET passwortcode = :passwortcode, passwortcode_time = NOW() WHERE id = :userid");
$result = $statement->execute(array('passwortcode' => sha1($passwortcode), 'userid' => $user['id']));
$empfaenger = $user['email'];
$betreff = "Neues Passwort für deinen Account auf www.php-einfach.de"; //Ersetzt hier den Domain-Namen
$from = "From: Vorname Nachname <[email protected]>"; //Ersetzt hier euren Name und E-Mail-Adresse
$url_passwortcode = 'http://localhost/passwortzuruecksetzen.php?userid='.$user['id'].'&code='.$passwortcode; //Setzt hier eure richtige Domain ein
$text = 'Hallo '.$user['vorname'].',
für deinen Account auf www.php-einfach.de wurde nach einem neuen Passwort gefragt. Um ein neues Passwort zu vergeben, rufe innerhalb der nächsten 24 Stunden die folgende Website auf:
'.$url_passwortcode.'
 
Sollte dir dein Passwort wieder eingefallen sein oder hast du dies nicht angefordert, so bitte ignoriere diese E-Mail.
 
Viele Grüße,
dein PHP-Einfach.de-Team';
mail($empfaenger, $betreff, $text, $from);
 
echo "Ein Link um dein Passwort zurückzusetzen wurde an deine E-Mail-Adresse gesendet.";
$showForm = false;
}
}
}
 
if($showForm):
?>
 
<h1>Passwort vergessen</h1>
Gib hier deine E-Mail-Adresse ein, um ein neues Passwort anzufordern.<br><br>
 
<?php
if(isset($error) && !empty($error)) {
echo $error;
}
?>
 
<form action="?send=1" method="post">
E-Mail:<br>
<input type="email" name="email" value="<?php echo isset($_POST['email']) ? htmlentities($_POST['email']) : ''; ?>"><br>
<input type="submit" value="Neues Passwort">
</form>
 
<?php
endif; //Endif von if($showForm)
?>

  1. Zuerst wird ihm ein Formular für seine E-Mail-Adresse angezeigt. (Zeilen 65-78)
  2. Danach wird überprüft, ob die E-Mail-Adresse zu einem Nutzer in der Datenbank passiert. Falls nicht, wird ihm eine entsprechende Fehlermeldung ausgeben. (Zeilen 22-31)
  3. Passt die E-Mail-Adresse, dann wird ein zufälliger Code generiert. Der sha1-Hash von diesem Code sowie der aktuelle Zeitpunkt wird in der Datenbank für den Benutzer gespeichert. (Zeilen 33-35)
  4. Zum Abschluss wird dem Nutzer eine E-Mail gesendet. In dieser findet er den Link zum Zurücksetzen seines Passworts. Dieser Link enthält zum einen sein Benutzer-ID, zum anderen den zuvor generierten Code. (Zeilen 38-54)

Der Code wird als sha1-Hash gespeichert, damit ein Angreifer der mittels SQL Injection keine Passwort-Codes stehlen kann um damit Benutzerpasswörter zu verändern. Ihr könnt dort potentiell auch jede andere Hashfunktion nutzen, dies macht von der Sicherheit keinen Unterschied.

Neues Passwort Vergeben

Nachfolgend die Seite, die ein Benutzer von der erhaltenen E-Mail aufruft um sein neues Passwort zu vergeben (passwortzuruecksetzen.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'passwort');
 
if(!isset($_GET['userid']) || !isset($_GET['code'])) {
die("Leider wurde beim Aufruf dieser Website kein Code zum Zurücksetzen deines Passworts übermittelt");
}
 
$userid = $_GET['userid'];
$code = $_GET['code'];
 
//Abfrage des Nutzers
$statement = $pdo->prepare("SELECT * FROM users WHERE id = :userid");
$result = $statement->execute(array('userid' => $userid));
$user = $statement->fetch();
 
//Überprüfe dass ein Nutzer gefunden wurde und dieser auch ein Passwortcode hat
if($user === null || $user['passwortcode'] === null) {
die("Es wurde kein passender Benutzer gefunden");
}
 
if($user['passwortcode_time'] === null || strtotime($user['passwortcode_time']) < (time()-24*3600) ) {
die("Dein Code ist leider abgelaufen");
}
 
 
//Überprüfe den Passwortcode
if(sha1($code) != $user['passwortcode']) {
die("Der übergebene Code war ungültig. Stell sicher, dass du den genauen Link in der URL aufgerufen hast.");
}
 
//Der Code war korrekt, der Nutzer darf ein neues Passwort eingeben
 
if(isset($_GET['send'])) {
$passwort = $_POST['passwort'];
$passwort2 = $_POST['passwort2'];
if($passwort != $passwort2) {
echo "Bitte identische Passwörter eingeben";
} else { //Speichere neues Passwort und lösche den Code
$passworthash = password_hash($passwort, PASSWORD_DEFAULT);
$statement = $pdo->prepare("UPDATE users SET passwort = :passworthash, passwortcode = NULL, passwortcode_time = NULL WHERE id = :userid");
$result = $statement->execute(array('passworthash' => $passworthash, 'userid'=> $userid ));
if($result) {
die("Dein Passwort wurde erfolgreich geändert");
}
}
}
?>
 
<h1>Neues Passwort vergeben</h1>
<form action="?send=1&amp;userid=<?php echo htmlentities($userid); ?>&amp;code=<?php echo htmlentities($code); ?>" method="post">
Bitte gib ein neues Passwort ein:<br>
<input type="password" name="passwort"><br><br>
 
Passwort erneut eingeben:<br>
<input type="password" name="passwort2"><br><br>
 
<input type="submit" value="Passwort speichern">
</form>

Das passwortzuruecksetzen.php Script hat den folgenden Aufbau:

  1. Zuerst wird überprüft, ob eine User-Id und ein Code übergeben wird. Ebenfalls wird überprüft, ob der Nutzer ein Passwordcode angefordert hat (Zeilen 4-19).
  2. Danach wird überprüft, dass der angeforderte Code noch nicht alter als 24 Stunden ist und natürlich dass der übermittelte Code aus dem GET-Parameter identisch zum abgespeicherten Code in der Datenbank ist. Da in der Datenbank der Hash des Codes gespeichert ist, muss hier erneut die Hashfunktion aufgerufen werden (Zeilen 21 - 29).
  3. Sollten alle Voraussetzungen erfüllt sein, so wird dem Benutzer ein Formular zum Ändern seines Passworts angezeigt. Hierbei muss er sein neues Passwort zwei mal eingeben (Zeilen 51 - 60).
  4. Drückt der Benutzer auf absenden, so wird überprüft, dass er zwei mal das gleiche Passwort eingegeben hat. Falls alles stimmt, so wird mittels password_hash() der Hashwert des Passworts gespeichert und in der Datenbank abgespeichert. Ebenfalls wird der Passwortcode gelöscht (Zeilen 33 - 48).
Autor: Nils Reimers
Zurück: Loginscript
Weiter: Angemeldet bleiben

Für Fortgeschrittene

  • Objektorientierte Programmierung
  • PHP Sicherheit
  • Script-Beispiele
    • Loginscript
      • Passwort vergessen
      • Angemeldet bleiben
    • E-Mails mit Anhang versenden
    • Gästebuch
    • PDFs erstellen
    • Besucherzähler mit Reload-Sperre
    • Kontaktformular
    • Logfiles mit PHP generieren
    • URLs im Text identifizieren
  • Codeschnipsel
  • Stellenmarkt
Mit freundlicher Unterstützung von:
  • Punkt191 Werbeagentur

Hoster – Geringste Ausfallzeit

  1. webgo Ø 0 Min.
  2. netcup Ø 0 Min.
  3. Linevast Ø 3 Min.
  4. All-Inkl.com Ø 3 Min.
  5. checkdomain Ø 5 Min.
  6. dogado Ø 6 Min.
  7. Strato Ø 8 Min.
  8. manitu Ø 9 Min.
  9. 1&1 Ø 10 Min.
  10. DomainFactory Ø 13 Min.
» Mehr erfahren

Impressum | Datenschutz | Auf PHP-Einfach.de werben

© PHP-Einfach.de 2003 - 2025

Cookie-Zustimmung verwalten
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Anbieter verwalten Lese mehr über diese Zwecke
Einstellungen ansehen
{title} {title} {title}