Benutzer-Anmeldung (PHP) - einige Fragen

Hallo,

ich bin schon wieder hier mit neuen Fragen. In meinem PHP5 Schmöker - mittleweile schon etwas in die Jahre gekommen - erfolgt die Anmeldung von Benutzern auf einer Website in etwa auf folgende Weise:

// ...
$abfrage = "select \* from benutzer where benutzername = '$benutzername' and passwort = sha1('$passwort');
$ergebnis = $db-\>query($abfrage);
$zeilen = $ergebnis-\>num\_rows;

if ($zeilen \> 0) {
 $\_SESSION['benutzer'] = $benutzername;
}

if (isset($\_SESSION['benutzer'])) {
 Mitgliederbereich
}

// ...

Ist diese Benutzeranmeldung noch Stand der Technik? Ich habe das Beispiel etwas erweitert, eine Anmeldung ist nur möglich, wenn der Account zuvor per E-Mail (Bestätigungslink) aktiviert wurde.

// ...
$abfrage = "select \* from benutzer where benutzername = '$benutzername' and passwort = sha1('$passwort');
$ergebnis = $db-\>query($abfrage);
$zeilen = $ergebnis-\>num\_rows;
$benutzer = $ergebnis-\>fetch\_assoc();

if ($zeilen \> 0) {
 $\_SESSION['benutzer'] = $benutzername;
}

if (isset($\_SESSION['benutzer'])) {
 if ($benutzer['aktivierungs\_id'] == 1) {
 Mitgliederbereich
 } else if ($benutzer['aktiverungs\_id'] == 2) {
 Account noch nicht aktiviert
 }
}

// ...

Die dazugehörige Datenbank sieht in etwa so aus:

create table benutzer
(
benutzer\_id int unsigned not null auto\_increment primary key,
benutzer\_name char(20) not null,
passwort char(40) not null,
email char(40) not null,
aktivierungs\_id tinyint unsigned not null,
aktivierungs\_code char(40) not null,
registrierung\_datum datetime not null
) engine=InnoDB default character set UTF8 collate utf8\_general\_ci;

Beim Erstellen des Accounts setze ich die Spalte aktivierungs_id auf „2“ (inaktiv) und schreibe einen zufällig generierten Code in die Spalte aktiverungs_code (mit sha1 verschlüsselt). Gleichzeitig versende ich eine Aktivierungslink an die angegebene E-Mail Adresse? Was ist denn von dieser Lösung zu halten? Ich bin leider nur ein Hobbieprogrammierer und kann daher keine professionelle Beurteilung in Sachen Sicherheit treffen. Alle GET und POST Variablen prüfe ich mit real_escape_string() und meist auch mit preg_match().

Vielen Dank, Elo!

Hallo Elo!

wieso können sich mehrere nutzer mit dem gleichen benutzernamen registrieren? ich vermute in deiner applikation folgendes szenario:
wenn ich zb der zweite user bin mit dem benutzernamen hans und versuche mich einzuloggen dann legt er die session aber für hans an der in der db vor mir steht, kann das sein?

welche zeichen filterst du überhaupt aus $benutzer und $passwort?

was ich noch nicht ganz verstehe warum du für ein user der inaktiv ist trotzdem eine session angelegst. der hat doch dann genauso zugang auf gesperrte seiten deiner homepage wie ein aktiver user, oder?!

lg favorite

Die Benutzernamen sind eindeutig. Bei der Registrierung frage ich ab, ob der Benutzername sich bereits in der Datenbank befindet und breche gegebenenfalls die Ausführung des Skriptes ab. Das gleiche mache ich mit der E-Mail Adresse.

Wenn der Benuter inaktiv ist, vergebe ich bei der Anmeldung keine Session (mein Fehler).

Die Prüfung von Benutzernamen und Passwort sieht (grob) folgendermaßen aus:

$db = db\_verbinden(); // Herstellung Datenbankverbindung (Funktionsbibliothek)
$\_POST = escape\_all($\_POST, $db); // aus Funktionsbibliothek (siehe unten)

/\*\*\*\*\* in Funktionsbibliothek
function escape\_all($var, $db) {
 if(is\_array($var)) {
 foreach($var as &$value) {
 $value = escape\_all($value, $db);
 }
 } else {
 $var = $db-\>real\_escape\_string($var);
 }
 return $var;
 }
\*\*\*\*\*/

// Zeichen-Prüfung Benutzername/Passwort (bereits bei Registrierung)
if (!preg\_match('/^[a-zA-Z0-9\_\-]{3,20}$/', $benutzername)) { 
// Fehlermeldung 
// exit();
}

if (!preg\_match('/^[a-zA-Z0-9\_\-]{6,30}$/', $passwort)) { 
// Fehlermeldung
//exit();
}

Wie wird den der Status aktiv/inaktiv in einer Datenbank in der Regel abgebildet? Ist meine Version brauchbar?

aber benutzername ist in deiner tabelle kein primärschlüssel bzw. unique das solltest du ändern und nicht nur in php kontrollieren!
ich machs immer so: wenn ein nutzer sich registriert bekommt er eine bestätigungsmail mit einem link der einen langen zufallsstring in der url enthält. wenn dann der user auf den link klickt wird er freigeschaltet und der zufallsstring aus der db gelöscht. so mach ich es halt.
damit der zufallsstring nicht erraten werden kann, erklär ich diese registrierung nach einer gewissen zeit als ungültig und lösch ihn aus der db.

aber achte nicht nur bei der registrierung/login darauf die werte zu filtern. du musst ALLES filtern was an dein server geschickt wird.

über sql injections solltest du bisschen im internet nachlesen. vielleicht hilft dir auch das hier scovetta.com/yasca.html

lg favorite

Die entsprechenden MySQL Spalten auf „unique“ zu setzen ist ein guter Tipp, danke!

Ändert der Benutzer seine E-Mail, lösche und zerstöre ich die Sessionvariable, um ihn auszuloggen. Gleichzeitig setze ich die Spalte aktivierungs_id wieder auf 2 (inaktiv) und schreibe einen neuen Aktivierungcode (Zufallstring) in die Spalte aktivierungs_code. Den Aktivierungslink (z.B. http://beispielseite.com/benutzeraktivierung.php?ben…) sende ich an die neue E-Mail Adresse. Der Zufallstring ist derzeit 12 Zeichen lang und besteht aus Zahlen, Groß- und Kleinbuchstaben. Wie leicht er sich erraten lässt, weiß ich leider nicht. Gibt es eine Motivation, sich mit einer fremden E-Mail anzumelden und dann den Code zu erraten?

Ich habe mich auch schon gefragt, ob ich in meine Tabelle „benutzer“ eine Spalte „mitglied_status“ hinzufügen sollte. Je nach Wert hat der Benutzer Mod Rechte, oder eben nicht. Über das Thema Benutzerverwaltung steht in meinem PHP Buch leider recht wenig, obwohl es beinahe 800 Seiten stark ist.

Die Variblen überprüfe ich übrigens immer, nicht nur bei der Registrierung. Ich habe mich leider missverständlich ausgedrückt und das Forum bietet keine Editierfunktion.

Danke für deine Hilfe!

ich kann dir über das thema benutzerverwaltung nicht viel sagen aber scheint eine komplexe sache zu sein die du vor hast. ich würde dir da eher empfehlen ein framework zu erlernen. ich persönlich arbeite mit cakephp:
http://book.cakephp.org/1.3/de/view/880/Was-ist-Cake…

es lässt sich schneller, viel strukturierter und auch sicherer programmieren. ich glaube eine benutzerverwaltung ist da im handumdrehen aufgebaut. schau es dir an ich habe es nie bereut.

also den zufallsstring kann man erraten und glaub nicht dass du nur nette besucher auf deiner webseite hast. aber wie lange jemand dafür braucht weiß ich nicht. hängt immer davon ab wie lang er string ist und wie viele verschiedenen zeichen drin sind(und die rechenleistung des users). 12 zeichen sollten genügen setz dann groß+klein buchstaben rein und zahlen. und schmeiß einfach alle anderen user aus der db raus die ihre email nicht bestätigt haben.

lg favorite :smile: