PHP: Login-System funktioniert nicht?
Hey, ich bin als Schüler gerade mit einem Partner dabei, an einem Projekt für den Informatikunterricht zu arbeiten. Aktuell arbeiten wir daran, dass man sich als Benutzer auf der Webseite anmelden kann.
Das Registrieren funktioniert bereits und als Vorlage diente uns dazu dieses Video:
https://www.youtube.com/watch?v=bNwT7pqVzDc
Nun sind in der Datenbank sowohl Benutzername als auch Passwort eingetragen. Als Benutzer soll man sich nun anmelden können und dann auf home.php weitergeleitet werden. Als Vorlage zum Anmelden verwendeten wir dieses Video:
https://www.youtube.com/watch?v=HrLucaAHLm8
Das Problem:
Wenn man versucht, sich auf der Webseite anzumelden, erscheint die Meldung "Passwort stimmt nicht ueberein", obwohl es übereinstimmen sollte. Hier ist der Quelltext:
<?php
require("connection.php");
if(isset($_POST["submit"])){
$Benutzername = $_POST["Benutzername"];
$Passwort = $_POST["Passwort"];
$stmt = $con->prepare("SELECT * FROM Angestellten_Benutzer WHERE Benutzername=:Benutzername");
$stmt->bindParam(":Benutzername", $Benutzername);
$stmt->execute();
$userExists = $stmt->fetchAll();
$passwordHashed = $userExists[0]["Passwort"];
$checkPassword = password_verify($Passwort, $passwordHashed);
if($checkPassword === false){
echo "Passwort stimmt nicht ueberein";
}
if($checkPassword === true){
session_start();
$_SESSION["Benutzername"] = $userExists[0]["Benutzername"];
header("Location: home.php");
}
}
?>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Anmelden</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form action="pp.php" method="POST">
<h1>Anmelden</h1>
<div class="inputs_container">
<input type="text" placeholder="Benutzername" name="Benutzername" autocomplete="off">
<input type="password" placeholder="Passwort" name="Passwort" autocomplete="off">
</div>
<button name="submit">Anmelden</button>
</form>
</body>
</html>
Ich würde mich sehr über eine Korrektur dieses Codes freuen. Der Validator sowie die KI scheinen keine Lösung für das Problem zu haben und keine Probleme zu erkennen. Danke!
3 Antworten
Ich würde das Ganze mal debuggen - mit Debugging Umgebung, oder wenigstens Debug-Ausgaben einführen. Zum Beispiel, was aus der Datenbank gelesen wird, welchen Wert $userExists hat... Aus dem Code geht nicht heraus, wie ihr die Spalten eurer Datenbank benannt habt. Heißt die Spalte für das Passwort "Passwort"? Richtige Groß-/Kleinschreibung ist hier wichtig...
Ist der Hash richtig gespeichert? Würde der Hash hart codiert im Skript funktionieren, also ohne Datenbank-Zugriff? Versucht mal euren Code systematisch zu testen und den Fehler einzugrenzen... Wenn ein Validator nichts findet, deutet das auf Datenfehler hin... Wobei hier auch Spaltennamen und Indizes von assoziativen Arrays falsch sein können - das kann ja erst zur Laufzeit ausgewertet werden.
Ich halte die Zeile für einen schlechten Stil:
$passwordHashed = $userExists[0]["Passwort"];
Was ist, wenn die Datenbank-Abfrage nicht erfolgreich war? wäre userExists ===false und man könnte nicht als Array darauf zugreifen, oder?
Ich habe lange nichts mehr mit PHP gemacht.
Antwort:
Der Quelltext ist korrekt. Das Problem schien an der Zeichenbegrenzung in der Datenbank gelegen zu haben.
Schreibe erstmal ganz am Anfang ini_set('display_errors',1); rein, damit dir Warnungen / Fehler angezeigt werden. Kannst du später wieder rausnehmen. Oder schaue im Log nach Fehlermeldungen.
Den Rückgabewert von $stmt->execute mal zu prüfen und im Fall false die Fehlermeldung aus $stmt->errorInfo()[2] mal anzeigen lassen könnte einen Hinweis geben. Zumindest wenn du irgendwelche Tabellen/Spaltennamen falsch hast. Groß-/Kleinschreibung ist da nicht egal.
Du solltest vor $passwordHashed = $userExists[0]["Passwort"]; erstmal schauen, ob da überhaupt Daten zurückkamen, wenn der Benutzername falsch ist, hast du da ein leeres Array. Also mit if (isset($userExists[0])) oder if ($stmt->rowCount()==1) erstmal prüfen.
Dein Problem wird aber sein, dass du beim Registrieren das Passwort im Klartext speicherst und dann aber mit password_verify prüfen willst. Das geht nicht, und Passwort im Klartext speichern ist böse. Wandele daher das Passwort direkt beim Registrieren in den passenden Hash vor dem INSERT um, indem du da $passwort=password_hash($passwort) o.Ä. aufrufst, bevor du das dem bindParam übergibst. Schaue nach, dass das Passwort-Feld in der DB lang genug für den Hash ist, da varchar(255) nehmen und nicht die Länge künstlich begrenzen...