PHP MySql Login / Passwort überprüfung?

3 Antworten

In Zeile 14 von login.php verwendest du die nicht definiert Variable $pdo statt $conn, also:

$statement = $conn->prepare("SELECT …

Die Fehlermeldung ist übrigens absolut aussagekräftig und du solltest versuchen, diese zu lesen und zu verstehen.

In Zeile 19 machst du aus einem String auf einmal ein Array:

$password['passwort']

Da sollte nur $password stehen. Allerdings solltest du dir noch mal die Dokumentation von password_verify ansehen:

https://www.php.net/manual/de/function.password-verify.php

Du vergleichst den Nutzernamen mit dem Passwort, was natürlich nicht funktionieren kann. Stattdessen musst du das eingegebene Passwort mit dem Passwort-Hash aus der Datenbank vergleichen. Dazu holst du dir den Hash vorher aus der Datenbank und testest ihn dann mit password_verify gegen das eingegeben Passwort.

Woher ich das weiß:Berufserfahrung – Entwickle seit > 20 Jahren Anwendungen mit PHP.

10tel  23.11.2022, 11:17
Stattdessen musst du das eingegebene Passwort mit dem Passwort-Hash aus der Datenbank vergleichen.

Wenn das Passwort einzigartig UNIQUE ist, üblicherweise wird das bei der Neuanlage/Änderung des Kontos nicht überprüft.

Babelfish  23.11.2022, 11:30
@10tel

Das Passwort muss nicht einmalig sein und das lässt sich mit einem Salt auch gar nicht überprüfen. Eindeutig muss nur der Nutzername sein.

10tel  23.11.2022, 11:35
@Babelfish

Mir ist das klar, aber deine Schreibe fand ich missverständlich:

Du vergleichst den Nutzernamen mit dem Passwort, was natürlich nicht funktionieren kann. Stattdessen musst du das eingegebene Passwort mit dem Passwort-Hash aus der Datenbank vergleichen.

Es sind sowohl Nutzername als auch Passwort abzugleichen, nicht „stattdessen“. Ich bin halt Programmierer und muss meinem Rechenknecht exakte Anweisungen geben.

Babelfish  23.11.2022, 12:12
@10tel

Du hast meinen letzte Satz vergessen zu zitieren, der genau erklärt, wie es gemacht wird:

Dazu holst du dir den Hash vorher aus der Datenbank und testest ihn dann mit password_verify gegen das eingegeben Passwort.

Einfach zu schreiben, dass man Nutzername und Passwort abgleichen muss, wäre nämlich auch missverständlich, weil man das eben üblicherweise nicht gleichzeitig macht. Erst holt man sich den Datensatz mit dem Nutzer über den Nutzernname und dann vergleicht man, ob der Passwort-Hash im Datensatz mit vom dem eingegeben Passwort übereinstimmt.

In einer Datenbankabfrage lässt sich das normalerweise nicht erledigen, da Passwörter immer mit einem zufälligen Salt versehen sein sollten.

Die Variable heißt doch $conn statt $pdo, wenn ich das richtig sehe.

Woher ich das weiß:Studium / Ausbildung – Datenverarbeitungs-Kfm, Hobby- und Profi-Programmierer

gfdsgsdgsdg 
Beitragsersteller
 26.07.2022, 02:33

Ok nächste Fehlermeldung mit der ich nichts anfangen kann xD

<br />
<b>Fatal error</b>: Uncaught TypeError: Cannot access offset of type string on string in C:\xampp\htdocs\Test\assets\php\login.php:19
Stack trace:
#0 {main}
 thrown in <b>C:\xampp\htdocs\Test\assets\php\login.php</b> on line <b>19</b><br />
DonkeyShot  26.07.2022, 02:45
@gfdsgsdgsdg

Lernst du erst programmieren? Dann mach bitte zuerst etwas anderes. Eine Sprache mit strikter Typisierung und Typprüfung zur Compilierzeit (C, VB, Java).

Zum Problem: Welches ist Zeile 19? Die mit

$password['passwort']

Was soll der Ausdruck bewirken?

gfdsgsdgsdg 
Beitragsersteller
 26.07.2022, 02:57
@DonkeyShot
Lernst du erst programmieren? Dann mach bitte zuerst etwas anderes. Eine Sprache mit strikter Typisierung und Typprüfung zur Compilierzeit (C, VB, Java).

Also JavaScript mache ich schon etwas länger aber noch lange kein Profi,

php ist mir aber echt ein rätsel und die Fehlermeldungen nicht so leicht

$password['passwort']
Was soll der Ausdruck bewirken?

Garnicht, Das ist schon peinlich xD

Danke hab es verbessert

    //Überprüfung des Passworts
    if ($user !== false && password_verify($username, $password)) {
        $_SESSION['userid'] = $user['id'];
        die('Login erfolgreich. Weiter zu <a href="geheim.php">internen Bereich</a>');
    } else {
        $errorMessage = "Nutzername oder Passwort war ungültig<br>";
        echo $errorMessage;
    }

Leider lande ich auch hier im Else teil

mit Nutzername oder Passwort war falsch

Obwohl es genau so in der Datenbank steht,

Hast du vielleicht noch ein paar fehler von mir entdecken können ?

KarlRanseierIII  26.07.2022, 02:58
@DonkeyShot

Sollte wohl einfach nur $password sein. Er hat das wohl imt dem schlüsselbasierten Zugriff bei $_POST verwechselt.

Mein Tipp wäre ja schlafen zu gehen udn it frischem Kopf weiter zu machen :-D.

KarlRanseierIII  26.07.2022, 03:00
@gfdsgsdgsdg

Du mußt das übermittelte Passwort gegen das Passworthash aus der Datenbank prüfen.

$user ist doch das gesamte Tupel.

gfdsgsdgsdg 
Beitragsersteller
 26.07.2022, 03:00
@DonkeyShot

Für php habe ich mich halt entschieden um schnell ein cooles Backend hinzubekommen,

Verglichen mit Java oder C ist das ja noch wenig aufwand auch wenn es seltsam ist.

Fokusiere mich eher auf Frontent

DonkeyShot  26.07.2022, 03:01
@gfdsgsdgsdg

Prüfe den Wert von "$user". Wenn das true ist, liegt's am Rückgabewert der Funktion password_verify. Da ich nicht weiß, was in der Funktion passiert, kann ich das schlecht beurteilen.

Statt "$user !==false" kannst du einfach "$user == true" schreiben oder einfach nur "$user". Bei letzterem bin ich mir nicht sicher, denn ich leider keine PHP.

EDIT: Hab mich in der Variable vergriffen. $result, nicht $user.

gfdsgsdgsdg 
Beitragsersteller
 26.07.2022, 03:10
@DonkeyShot
    //Überprüfung des Passworts
    if ($user !== false && password_verify($password, $user['password'])) {
        $_SESSION['userid'] = $user['id'];
        die('Login erfolgreich. Weiter zu <a href="geheim.php">internen Bereich</a>');
    } else {
        $errorMessage = "Nutzername oder Passwort war ungültig<br>";
        echo $errorMessage;

hab es doch noch hinbekommen, das hat funktioniert 
Gute nacht und danke für die hilfe 😂

Mit === true aber irgendwie nichtmehr, obwohl es eigentlich dasselbe heisst
gfdsgsdgsdg 
Beitragsersteller
 26.07.2022, 02:30

Ja heisst sie, glaube der fehler liegt hier

$statement = $pdo->prepare("SELECT * FROM user WHERE username = :username");

müsste

$statement = $conn->prepare("SELECT * FROM user WHERE username = :username");

sein

Um den Fehler zu beheben, müssen Sie die Variable $pdo in Zeile 14 durch $conn ersetzen. Der korrigierte Code sollte wie folgt aussehen:
<?php

$server = 'localhost';

$user = 'root';

$psw = null;

$dbName = 'TestApp';

try {

$conn = new PDO('mysql:host='.$server.';dbname='.$dbName.';charset=utf8', $user, $psw);

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$username = htmlspecialchars(stripslashes(trim($_POST['username'])));

$password = htmlspecialchars(stripslashes(trim($_POST['password'])));

$statement = $conn->prepare("SELECT * FROM user WHERE username = :username");

$result = $statement->execute(array('username' => $username

));

$user = $statement->fetch();

//Überprüfung des Passworts

if ($user !== false && password_verify($username, $password['passwort'])) {

$_SESSION['userid'] = $user['id'];

die('Login erfolgreich. Weiter zu <a href="geheim.php">internen Bereich</a>');

} else {

$errorMessage = "Nutzername oder Passwort war ungültig<br>";

}

}catch (PDOException $e) {

print "Error!: " . $e->getMessage() ;

exit;

}

?>