Problem mit LogIn | Überprüft nicht richtig
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abfrage
anzahl
beispiel
code
datenbank
ding
einloggen
funktion
login
machen
nutzer
pferd
problem
rest
sache
sagen
session
sonderzeichen
steckbrief
zeichen
-
Ich habe nun seit längerem den LogIn. Doch er überprüft die Daten nicht richtig. Wenn ich auf den Button klicke, werde ich immer eingeloggt, egal was ich eingebe. Wenn ich jedoch Nickname UND (!) Passwort falsch eingebe, klappt es nicht.
Ich finde übrigens keinen Fehler in dem Code und bastel schon Jahre (ich übertreib^^) dran rum.
<?php session_start(); ?> <html> <head> <title>equineStars</title> <link rel="stylesheet" type="text/css" href="designcss.css"> </head> <body background="content.png" scroll="no"> <?php include("datenbank.php"); $Nickname = $_POST["Nickname"]; $Passwort = $_POST["Passwort"]; $abfrage = "SELECT Nickname, Passwort FROM Steckbrief WHERE Nickname LIKE '$Nickname' LIMIT 1"; $ergebnis = mysql_query($abfrage); $row = mysql_fetch_object($ergebnis); if($row->Passwort == $Passwort) { $_SESSION["Nickname"] = $Nickname; echo '<div align="justify"> <table border="0" cellpadding="5" width="100%"> <tr> <td width="12%" bgcolor="#FEE7C2"> <p align="center"><a href="login_allgemeines.php"><b>Allgemeines</b></a></td> <td width="12%" bgcolor="#FEE7C2"> <p align="center"><a href="login_profil.php">Profil</a></td> <td width="12%" bgcolor="#FEE7C2"> <p align="center"><a href="login_pferde.php">Pferde</a></td> <td width="12%" bgcolor="#FEE7C2"> <p align="center"><a href="login_stadt.php">Stadtmitte</a></td> <td width="13%" bgcolor="#FEE7C2"> <p align="center"><a href="login_bericht.php">Berichte</a></td> <td width="13%" bgcolor="#FEE7C2"> <p align="center"><a href="spiele.php">Spiele</a></td> <td width="13%" bgcolor="#FEE7C2"> <p align="center"><a href="login_konto.php">Konto</a></td> </table> </div><br><br> Hallo'; } else { echo "Login fehlgeschlagen!<br><a href=\"login.htm\">Zurück</a>"; } ?> </html> </body>
Ich hab ihn von php-einfach.de
LG -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Wie wär's mit:
$rs = mysql_query ("select count(*) as cnt from Steckbrief where nickname like '$Nickname' and passwort = '$Passwort'"); $row = mysql_fetch_assoc ($rs); if ($row ["cnt"] == 0) { echo "Login failed"; // weitere Anweisungen für diesen Fall. } else { echo "Login successful"; // weitere Anweisungen für diesen Fall. }
Des weiteren scheint es, dass du die Passwörter deiner Kundschaft in Klartext speicherst. Das ist in meinen Augen sehr unhöflich. Ein beliebiger Hash vom Passwort reicht voll und ganz aus.
cu -
Danke! Darauf wär ich nie gekommen. Da kann sogar noch mein Vater von lernen^^
Mit dem MD5 und all dem anderem Kram kenn ich mich so gut wie gar nicht aus und kapiers auch nicht. Deshalb dachte ich mir, dass es auch so gehen könnte. Oder gibt es dann Schwierigkeiten/Probleme/...? -
wenns du's nicht verschlüsselsts, kann halt jeder der zugriff zur datenbank hat die passwörter nachlesen. wenns verschlüsselt is gehts nicht mehr, weil md5 als "nichtentschlüsselbar" gilt... also einmal verschlüsselt kanns keiner mehr zurückverfolgen
-
Das Ding steht genau so auf php-einfach? Dann sind die einfach dämlich!
Das Script hat nämlich eine entscheidende Sicherheitslücke.
Die Usereingaben werden ungeprüft und ungefiltert in die Query eingebaut:
$Nickname = $_POST["Nickname"]; $Passwort = $_POST["Passwort"]; $abfrage = "SELECT Nickname, Passwort FROM Steckbrief WHERE Nickname LIKE '$Nickname' LIMIT 1";
Ein Schelm schiebt dir dort schnell eine SQL-Injection unter und zerschießt dir die Datenbank.
FF
Beitrag zuletzt geändert: 17.7.2009 19:13:32 von fatfreddy -
Also Grunsätzlich ist zu sagen, das man keiner User Eingabe trauen sollte, selbst nicht den Eigenen! Sprich jeder Wert der in die Datenbank soll muss geprüft werden ob er auch das enthällt was er enthalten soll. Zwar kann man mit mysql_real_escape_string(), recht einfach einen String der in die Datenbank soll escapen, aber das ist nur die kleine Lösung.
Schon bei einer Abfrage die nur einen Integer Wert abfragen/prüfen soll, ist mysql_real_escape_string() zu viel des guten. Ein einfaches is_integer($wert) reicht völlig aus. Bei Namen und Passwörtern reicht eine Prüfung auf alphanumerischen Zeichen, bzw. den standard Sonderzeichen. Es hilft auch die Länge der Namen zu begrenzen, ca. 20-25 Zeichen reichen völlig aus für einen Nick.
An dieser Stell würde ich Dir empfehlen dich mal mit REGEX und der Funktion preg_match() ein wenig auseinander zu setzen. Dies ist zwar ein sehr komplexes Thema, aber es wird Dir ungemein helfen wenn Du dass beherscht und REGEX ist in vielen anderen Script- und Prommaiersprachen vertreten. Somit kann es nicht schaden wenn man es kann.
@census: COUNT(*) ist immer so ne Sache, ein spezifischer Wert, zum Beispiel COUNT(ID), reicht völlig aus und macht die Abfrage ein wenig schneller. Aber warum Like, wenn man nach einem bestimmten Wert sucht? "...WHERE Nickname = '$nickname'..." reicht da völlig aus. -
strange schrieb:
@census: COUNT(*) ist immer so ne Sache, ein spezifischer Wert, zum Beispiel COUNT(ID), reicht völlig aus und macht die Abfrage ein wenig schneller. Aber warum Like, wenn man nach einem bestimmten Wert sucht? "...WHERE Nickname = '$nickname'..." reicht da völlig aus.
Das "where" hinter dem Nick habe ich vom original-Post übernommen. Ich nehme an es dient dazu, dass der Nicknamevergleich case-insensitive ist. Wobei ein LOWER () o.ä. auf beiden Seiten weniger teuer sein dürfte, aber die Logindatenbank einer privaten Homepage wird die DB-Engine wohl nie an ihre Grenzen bringen.
Warum ist COUNT (colname) schneller als COUNT (*)?
COUNT(*) geht doch auch nur über die interne Row-ID der DB-Engine oder lieg ich da falsch? Und die Anzahl der angezogenen Zeilen ist ja -hoffentlich- dieselbe.
Beitrag zuletzt geändert: 17.7.2009 21:28:55 von census -
Das "Ding" stand nicht so auf php-einfach, sondern mit der verschlüsselten Variante. Nur da ich Probleme damit hatte und das PW nicht richtig eingeben konnte, hab ich es weggelassen.
Müsste ich in dem Code für login.php nun einfach bei den Variablen das md5 da hinschreiben, also $Passwort = md5($_POST["Passwort"]); und die Anmeldung eben anpassen, oder noch etwas ändern?
Da ich mich erst seit ein paar Monaten mit PHP & MySQL beschäftige, kann ich es auch nicht sehr gut bzw. so gut wie gar nicht. Bin also noch in der Lernphase (was ich besonders in den Sommerferien ausnutzen werde), obwohl ich recht schnell vorranschreite. Kenne daher noch nicht alle Begriffe, die man in dieser Sprache verwendet, sondern eben nur ein paar.
Was ist eigentlich rs (das es eine Variable ist, ist mir klar. Doch warum ausgerechnet der Name?), cnt und count? Mag ja auch den Code verstehen, den ich verwende (sonst lern ich ja nichts).
Ansonsten nochmals vielen Dank! Hab wochenlang rumgesucht und nichts gefunden... -
Wie du schon richtig erkannt hast, sind "rs" und "cnt" nur frei gewählte Namen, da könnte auch "Gurkenscheibe" und "Phasengegenspulautomat" stehen.
Ich habe "rs" gewählt, weil die Variable das "Result Set" der Query beinhaltet.
"cnt" steht einfach für "count", also die Anzahl der Reihen.
"COUNT()" wiederrum ist nicht freigewählt sondern eine SQL-Aggregatfunktion.
Das ganze funktioniert wie folgt:
Die Query liefert die Anzahl der Zeilen zurück, bei denen Nickname und Passwort mit der Eingabe übereinstimmen.
Falls die Query 0 liefert, also keine Zeilen gefunden wurden, steht diese Kombination an Nick und Pw nicht in der DB und ergo darf man sich mit diesen Credentials nicht anmelden.
Falls die Query nicht 0 liefert, dann existiert der Nutzer mit dem Passwort und er darf sich anmelden.
Was nicht berücksichtigt ist, ist das Verhalten, wenn es mehrere Nutzer mit demselben Namen und demselben Passwort gibt. Aber das solltest du bereits beim Anlegen der Nutzer verhindern.
Beitrag zuletzt geändert: 17.7.2009 21:53:19 von census -
Warum ist COUNT (colname) schneller als COUNT (*)?
COUNT(*) geht doch auch nur über die interne Row-ID der DB-Engine oder lieg ich da falsch? Und die Anzahl der angezogenen Zeilen ist ja -hoffentlich- dieselbe.
Count ist eine nicht ganz triviale Sache. Wenn eine Selektion stattfindet, es also eine WHERE-Klausel gibt dann wird unter allen MySQL-DB-Engines nur ein schneller Index Scan durchgeführt. Wenn aber keine Selektionsbedingung existiert, dann wird das von verschiedenen Datenbankengines anders behandelt. MyISAM hat einen internen Counter, aus dem das ausgelesen wird. InnoDB müsste dagegen einen sehr langsamen voollständigen Tabellenscan durchführen.
Aber, es handelt sich hier um den ersten Typ, also sollte das kein Problem sein.
Allgemein versuche ich jedoch das Count zu umgehen und mit if(mysql_num_rows) zu prüfen. (Oder der jeweiligen Funktion, die die Klasse zur Verfügung stellt).
strange schrieb:Bei Namen und Passwörtern reicht eine Prüfung auf alphanumerischen Zeichen, bzw. den standard Sonderzeichen.
Es ist sehr fragwürdig zu prüfen, ob ein Passwort alphanumerisch ist. Leute die das prüfen gehören gehängt, es stresst einfach, wenn ich mir ein sicheres PW generiere und der Service dann labert, dass nur alphanumerische Zeichen unterstützt werden. Das PW wird sowiso gehasht und niemals ausgegeben, also sollten die Zeichen, aus denen es besteht irrelevant sein. Auch wenn ich irgendwelche chinesischen drin habe...
Das "where" hinter dem Nick habe ich vom original-Post übernommen. Ich nehme an es dient dazu, dass der Nicknamevergleich case-insensitive ist. Wobei ein LOWER () o.ä. auf beiden Seiten weniger teuer sein dürfte, aber die Logindatenbank einer privaten Homepage wird die DB-Engine wohl nie an ihre Grenzen bringen.
Dann lieber Collation ändern auf ci. Beispielweise utf8_unicode_ci.
€dit: Nochwas vergessen. Wenn man auf ganzen Tabellen arbeitet, dann ist Count(*) sogar vor zu ziehen. Das Counten einer Spalte zählt nur die NOT NULL Werte und um die zu ermitteln, könte ein Table San nötig sein und das Auslesen des Counters nicht mehr genügen.
Beitrag zuletzt geändert: 17.7.2009 22:09:28 von nikic -
Ja beim PW ist das immer so eine Sache mit den Zeichen. Deswegen habe ich auch noch nen Sonderzeichen mit einbezogen. Diese sollte man aber schon ein wenig begrenzen, dann gibt es da keine Schwirigkeiten. Wenn man nen Passwort generiert kann man auch dort die verwendeten Zeichen begrenzen und somit ist es kein Problem ein Passwort zu generieren was nur aus alphanumerischen Zeichen besteht.
-
Ich hab nun wieder ein Problem.
Mein LogIn besteht aus mehreren Seiten. Nun will ich ja, dass man eingeloggt ist, um es zu sehen und füge deshalb vor jede Seite hier das:
<?php session_start(); ?> <?php if(!isset($_SESSION["Nickname"])) { echo "Du bist nicht eingeloggt. Bitte erst <a href=\"login.htm\">einloggen</a>"; exit; } ?>
Doch jetzt erscheint das "Du bist nicht eingeloggt" blablabla auch, wenn ich eingeloggt bin.
Edit: Auch wenn ich ein Mitglied zum Beispiel mit Namen <? echo $_SESSION["Nickname"];?> ansprechen will, klappt das nicht...
Beitrag zuletzt geändert: 18.7.2009 10:28:49 von equinestars -
Also ich habe die funktion empty benutzt.
if(empty($_SESSION["Nickname"]))
{
echo "Du bist nicht eingeloggt. Bitte erst <a href=\"login.htm\">einloggen</a>";
exit;
}
Ich weiß nicht ob es an deinem negator vor isset liegt. Versuch es einfach mal mit empty, sollte ja theoretisch das selbe sein. -
Das klappt auch nicht.
Ist eigentlich auch nicht schlimm, wenn nicht eingeloggte Benutzer alles lesen können, da sonst nur "Du hast keine Pferde!" und so erscheint, aber die Benutzer sollen ja ihre Pferde dann auch sehen und pflegen können ;) -
ich würde sagen, dass du entweder dann etwas im session ding drin stehen hast, oder du schließt den rest nicht aus.
Wenn der rest NICHT im else teil ist, wird der natürlich immer angezeigt. Also entweder du lässt die funktion "sterben"
<?php session_start(); ?> <?php if(empty($_SESSION["Nickname"])) { die "Du bist nicht eingeloggt. Bitte erst <a href=\"login.htm\">einloggen</a>"; exit; } ?>
ODER du setzt den rest in einen else Teil.
<?php session_start(); ?> <?php if(empty($_SESSION["Nickname"])) { echo "Du bist nicht eingeloggt. Bitte erst <a href=\"login.htm\">einloggen</a>"; exit; } else { echo"Du bist eingeloggt"; } ?>
Beitrag zuletzt geändert: 18.7.2009 11:37:57 von saalko -
Das klappt nicht...
Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in /home/webpages/lima-city/equinestars/html/equineStars/login_pferde.php on line 8
Und beim zweiten ist werde ich immer noch nicht eingeloggt... -
Zuerst solltest Du verstehen wie Sessions arbeiten. Erstens jede Session bekommt eine SessionID (SID) und wird entweder via Cookie an den Client übertragen, oder wenn die Cookies aus sind garnicht! Sprich Du musst an die Links immer die SID mit dran hängen, damit diese auch übertragen wird:
echo '<a href="index.php?'SID'">Home</a>':
Wichtig dabei ist die Konstante "SID", wenn die Cookies deaktiviert sind, wird dort die SID angehängt. Aber sie stellen ein kleines Sicherheitsrisiko dar, weil man aus Versehen doch gerne mal seine SessionID mit in einen Link Pakt und man somit anderen seine Session schenkt. Deswegen sollte man in der Session auch die IP Adresse des Client schreiben und bei jedem Seitenaufruf prüfen.
<?php if(isset($_SESSION['IP'], $_SESSION['UserID']) { if($_SESSION['IP'] != $_SERVER['REMOTE_ADDR']) { die('Ups, da hast Du wohl ne falsche Session erwischt.'); } } else { // Login zeigen -> } ?>
Wie Dir aufgefallen ist, habe ich nicht den Nickname in die Session geschrieben sondern, die UserID... das ist um einiges besser, da man in den meisten Fällen maximal 4 Zeichen hat die in die Session geschrieben werden und man über die UserID die netsprechenden Inhalte nachladen kann, ohne großen Aufwand gegen Injections betreiben zu müssen (is_integer($_SESSION['UserID'])).
Falls dieser Ansatz wieder nicht funktioniert, pack bitte mal den kompletten LoginScript in den nächsten Beitrag, vllt. finden dort den Fehler ;)
Beitrag zuletzt geändert: 18.7.2009 21:17:33 von strange -
Ich benutze nun diesen Code:
<?php session_start(); $was = $_POST["Nickname"]; if(!isset($was)) { $was = "Nickname"; } if($was == "Nickname") { $_SESSION['Nickname'] = $Nickname; ?> TEXT BLABLABLA <?php } ?>
Das klappt bisher auch ganz gut.
Dieses ?'SID' hinten dran bewirkt bei mir aber irgendwie gar nichts. Vielleicht dauert es wieder, bis alles aktuellisiert ist... -
equinestars schrieb:
Ich benutze nun diesen Code:
<?php session_start(); $was = $_POST["Nickname"]; if(!isset($was)) { $was = "Nickname"; } if($was == "Nickname") { $_SESSION['Nickname'] = $Nickname; ?> TEXT BLABLABLA <?php } ?>
Das klappt bisher auch ganz gut.
Dieses ?'SID' hinten dran bewirkt bei mir aber irgendwie gar nichts. Vielleicht dauert es wieder, bis alles aktuellisiert ist...
Wie und wohin speichert man dies??? -
Die Konstante SID wird auch nur mit übertragen, wenn man Cookies die deaktiviert hat. Sprich statt über $_GET, wird die SessionID über $_COOKIE geholt (das macht session_start() automatisch).
@equinestars: Dein Code ist irgend wie nicht wirklich praktisch und sicher schon garnicht. Weder eine abfrage für ein Passwort ist eingebaut und so weiter... hab jetzt keine Lust alles aufzuzählen.
@bettag: Am besten schaust Du Dir erst einmal ein Tutorial an, was Sessions genauer behandelt, damit Du weißt wie diese funktionieren und was man alles beachten muss. Außerdem kann es nicht schaden wenn Du mal das Q-Net PHP Tutorial durchgehst (am besten Kapitel für Kapitel). Dann sollte das alles ein wenig einfacher für Dich sein. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage