Paul: Verbesserungen, Kritik, Meinungen

0 66

Verbesserungen, Kritik, Meinungen

Paul
  • php
  1. 0
    Jörg Reinholz
    1. 0
      Paul
      1. 0
        ChrisB
        1. 0
          Paul
          1. 0
            Jörg Reinholz
            1. 0
              Paul
              1. 0
                Jörg Reinholz
                • programmiertechnik
                1. 0
                  Paul
                  1. 0
                    Jörg Reinholz
                    1. 0

                      Wir nähern uns dem Ziel? : )

                      Paul
                      1. 0
                        Jörg Reinholz
                        1. 0
                          Paul
                          1. 1
                            dedlfix
                            1. 0

                              php update

                              Paul
                              1. 0
                                dedlfix
                                1. 0
                                  Paul
                                  1. 0
                                    dedlfix
                                  2. 0
                                    Jörg Reinholz
                                    1. 0

                                      ohje

                                      Paul
                                      1. 0
                                        Jörg Reinholz
                                        1. 0
                                          Paul
                                          1. 0
                                            Jörg Reinholz
                                            1. 0

                                              Danke an dedlfix und Jörg Reinholz

                                              Paul
                                            2. 0
                                              Bobby
                                              1. 0
                                                Sven Rautenberg
                                                1. 0
                                                  dedlfix
                                                  1. 0
                                                    Sven Rautenberg
                                                    1. 0
                                                      Jörg Reinholz
                                                    2. 0
                                                      dedlfix
                                                      1. 0
                                                        Sven Rautenberg
                                                2. 0
                                                  Bobby
                                                  1. 0
                                                    Sven Rautenberg
                                                    1. 0
                                                      Jörg Reinholz
                                                    2. 0
                                                      Bobby
                                  3. 0
                                    Jörg Reinholz
                            2. 0
                              Jörg Reinholz
                              1. 1
                                Sven Rautenberg
                                1. 0
                                  Jörg Reinholz
                            3. 1
                              Matti Mäkitalo
                        2. 0

                          Kopfkino

                          Paul
                          1. 0
                            Jörg Reinholz
          2. 0

            Antwort II

            Jörg Reinholz
      2. 0

        sha1 ist tot.

        Jörg Reinholz
  2. 0

    NACHTRAG url

    Paul
    1. 0
      ChrisB
      1. 0
        Paul
  3. 0
    hotti
    1. 0

      speichern in $_SESSION

      Paul
      1. 0

        Objekt für die Userdaten

        hotti
        1. 0
          Paul
  4. 0
    Jörg Reinholz
    • selfhtml-wiki
    1. 0
      Matthias Apsel
      1. 0
        Jörg Reinholz
        1. 0
          Matthias Apsel
          1. 0
            Jörg Reinholz
    2. 0
      Matthias Apsel
    3. 0
      hotti
      1. 0
        Mitleser
        1. 0
          Jörg Reinholz
    4. 0

      Zu diesem Zweig: hier get es weiter (Link)

      Jörg Reinholz
    5. 1
      Christian Kruse
      1. 0
        Jörg Reinholz
        1. 0
          Christian Kruse
          1. 0
            Jörg Reinholz
            1. 0
              Christian Kruse

Guten Abend,

ich habe auf Grundlage des SELFHTML Artikels den Login auf einer meiner kleinen Privatprojekte erweitert.

...


<?php
include('msg.php');
# session erneuern
session_start();
if($_SERVER['REQUEST_METHOD'] == "POST"){
	if(empty($_POST['username']) || empty($_POST['password'])){
		$message = "";
		if(empty($_POST['username'])){
			$message = '<p>' . EMPTY_USERNAME . '</p>';
		}
		if(empty($_POST['password'])){
			$message .= '<p>' . EMPTY_PASSWORD . '</p>';
		}
	}
	else{
		$server = 'mysql:dbname=***;host=localhost; port=3306';
		$dbuser = '***';
		$dbpassword = '***';
		$options = array(
                     PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
				     PDO::MYSQL_ATTR_READ_DEFAULT_FILE => '/etc/my.cnf'
				   );
		$pdo = new PDO($server, $dbuser, $dbpassword, $options);
		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
		
		$username = $_POST['username'];
		$password = md5($_POST['password']);
		
		$query = "SELECT * FROM user WHERE username = :USERNAME AND password = :PASSWORD LIMIT 1";
		$stmt = $pdo->prepare($query);
		$stmt->bindValue(":USERNAME", $username, PDO::PARAM_STR);
		$stmt->bindValue(":PASSWORD", $password, PDO::PARAM_STR);	
		$stmt->execute();
		if($stmt->rowCount() == 1){
			if($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.1'){
				if(php_sapi_name() == 'cgi'){
					 header('Status: 303 See Other');
				}
				else{
					header('HTTP/1.1 303 See Other');
				}
			}
			$_SESSION['loggedIn'] = true;
			header('Location: http://schwalbennest.unwichdsch.de/index.php');
			exit;
		}
		else{
			 $message = '<p>' . LOGIN_INCORRECT . '</p>';
		}
	}
}
?>

....

Formular zum Login

Kann ich an dem Script noch etwas verbessern? Bin euch für jeden Hinweis dankbar.

LG Paul

  1. md5($_POST['password']);

    MD5 soll nicht mehr verwendet werden, weil es unsicher ist.

    Jörg Reinholz

    1. md5($_POST['password']);

      MD5 soll nicht mehr verwendet werden, weil es unsicher ist.

      Jörg Reinholz

      Besser sha1?

      :/

      1. Hi,

        MD5 soll nicht mehr verwendet werden, weil es unsicher ist.

        Besser sha1?

        Mindestens. Und salzen.

        MfG ChrisB

        --
        Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
        1. Hi,

          MD5 soll nicht mehr verwendet werden, weil es unsicher ist.

          Besser sha1?

          Mindestens. Und salzen.

          MfG ChrisB

          Was bedeutet "salzen"?

          LG Paul

          1. MD5 soll nicht mehr verwendet werden, weil es unsicher ist.

            ...

            Was bedeutet "salzen"?

            Schau in den Link.

            Jörg Reinholz

            1. MD5 soll nicht mehr verwendet werden, weil es unsicher ist. ... Was bedeutet "salzen"? Schau in den Link.

              Jörg Reinholz

              Kannst du mir das bitte erklären? Ich kapiere das nicht. :/

              LG Paul

              1. Kannst du mir das bitte erklären?

                Alls hash-verfahren haben ein Manko: Mittels rainbow-tables (große, aber inzwischen händelbare Datenmengen) lässt sich aus einem hash (das ist es, was md5(string), sha1(string) u.s.w. liefert) EIN (es muss im Hinblick auf (Stichwort:)Kollisionen nicht der ursprüngliche sein) String ermitteln, der passt.

                Um das verfahren zu erschweren:

                man baue einen string der Länge n aus ziemlich zufälligen Zeichen. Das ist der Salt.

                m Mal:     string=salt+string     string=hache(string) :danach, je nach Verfahren: string = "$" + Kennzeichen für hash-Verfahren + $ + 'rounds=' $m $ + salt + $ string; oder, wenn rounds schon mit dem verfahren fest gelegt ist: string = "$" + Kennzeichen für Verfahren + $ + salt + $ string;

                Tja. string ist jetzt das m-fach gesalzene und gehashte Passwort.

                Jörg Reinholz

                1. Ich kapiere es nicht. Vielleicht liegt es auch an der Uhrzeit.

                  Das Salz ist quasi eine zufällige Zeichenkette um den Hash der Beispielfunktion

                  md5('test') = 1234567890;

                  zu

                  md5('test_MEINSALZ') = 0987654321;

                  zu erzeugen?

                  LG Paul

                  1. Ich kapiere es nicht. Vielleicht liegt es auch an der Uhrzeit.

                    nicht ganz.

                    Das Salz wird auf das Brot gestreut und dann mit gegessen; Und je nach Salz und Menge schmeckt es jedesmal etwas anders.

                    statt string=md5(string) wird 5000 mal: string=md5(salz.string) gemacht.

                    Und außerdem wird weder md5() noch sha1() verwendet!

                    Und ja. das Ergebnis ist für jeden Salt ein anderes. Es geht darum, die notwendigen Tabellen aufzublähen.

                    Jörg Reinholz

                    1. Ok,

                      den habe ich kapiert. Es geht also darum die vorhandenen RAINBOW-TABLES zu "umgehen", bzw. deren Inhalt gespeicherter Passwörter aus den verschiedensten Verschlüsselungen.

                      Was genau kann bzw. muss ich tun? Das kapiere ich noch immer nicht.

                      :?

                      Sorry.

                      Keine md5() oder sha1(), oder oder oder. Wie erzeuge ich einen Hash der nicht durch die Funktionen md5() und Co. generiert werden? Mit deiner Bibliothek.

                      Wo muss ich denn da das Passwort eingeben?

                      LG Paul.

                      P.s: Soweit alles korrekt verstanden?

                      1. Es geht also darum die vorhandenen RAINBOW-TABLES zu "umgehen"

                        Nein. Aber man müsste für jeden verwendeten Salt neue erzeugen (kostet viel Zeit) oder gespeichert haben (kostet dann sehr viel mehr Speicherplatz)

                        Mit deiner Bibliothek.

                        Es ist nicht wirklich eine. Es ist eher ein Demonstrationsprogramm.

                        Wo muss ich denn da das Passwort eingeben?

                        Das Skript enthält ein paar Funktionen:

                        fastix_hash_passwd ($string) - erzeugt einen mehrfach gesaltzen und gehashten String (das wäre das Passwort) - mit dem besten (derzeit) in der konkreten PHP-Version möglichen Verfahren.

                        Verwende das so wie bisher md5().

                        create_salt() Hilfsfunktion, die einen brauchbaren Salt erzeugt.

                        fastix_check_passwd ($string, $string_hashed, $error_exit=false) nimmt einen String (das wäre das Passwort) und einen mit fastix_hash_passwd() gehashten und testet, ob die zusammenpassen.

                        test_me() - verschiedene Tests.

                        Den Rest lernst Du durch debuggen. Lasse Dir also an interessanten Stellen die Werte von interessanten Variablen ausgeben. Welche das sind? Lerne zu debuggen.

                        Noch was: Du verwendet ein Formuar. Daten aus Formularen sollte man auch noch durch trim(string) schicken, damit die oft versehentlich am Beginn oder Ende eingegebenen Leerzeichen gekillt werden.

                        Jörg Reinholz

                        1. Ich schaue mir das "morgen" früh mal an. Ich bin aktuell raus. Ist einfach zu spät.

                          Danke Jörg. :)

                          Bitte schau morgen nochmal hier rein, das wird ohne weitere Frage und Hilfe sicher nicht funktionieren. :/

                          Lg Danke Paul

                          1. Tach!

                            Ich schaue mir das "morgen" früh mal an. Ich bin aktuell raus. Ist einfach zu spät.

                            Im Allgemeinen wird übrigens sehr empfohlen, die vorhandenen Methoden zu verwenden und keine selbst erstellten Algorithmen zu nehmen. Letztere werden im Gegensatz zu ersteren kaum von einer relevanten Anzahl an Sicherheitsexperten auf Schwachstellen abgeklopft. Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                            dedlfix.

                            1. Tach!

                              Ich schaue mir das "morgen" früh mal an. Ich bin aktuell raus. Ist einfach zu spät.

                              Im Allgemeinen wird übrigens sehr empfohlen, die vorhandenen Methoden zu verwenden und keine selbst erstellten Algorithmen zu nehmen. Letztere werden im Gegensatz zu ersteren kaum von einer relevanten Anzahl an Sicherheitsexperten auf Schwachstellen abgeklopft. Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                              dedlfix.

                              Dafür musste ich php von 5.4 auf 5.6 updaten. :) Schön das ich das selber in der Hand habe.

                              Trotz allem habe ich ein .

                              LG Paul

                              1. Tach!

                                Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash(). Dafür musste ich php von 5.4 auf 5.6 updaten. :) Trotz allem habe ich ein .

                                Die genannte Funktion übernimmt das Klartext-Passwort und erzeugt daraus einen String, der sowohl fix und fertig speicherbar ist als auch der Funktion password_verify() zum Vergleichen übergeben werden kann. Damit hast mit jeweils einem einzigen Funktionsaufruf ein verwendbares Ergebnis.

                                dedlfix.

                                1. Hi dedlfix,

                                  erstmal danke. Ich habe jetzt etwas probiert. Das kam dabei raus:

                                  
                                  $pw = 'paul';
                                  
                                  $options = [
                                      'salt' => '1234567890abcdefghijklmnopqrstuvwxyz',
                                  ];
                                  
                                  echo $hash = password_hash($pw, PASSWORD_DEFAULT, $options);
                                  
                                  $testpw = 'kalle';
                                  
                                  if(password_verify($testpw, $hash)){
                                  	echo 'passt';	
                                  }
                                  else{
                                  	echo 'passt nicht';
                                  }
                                  
                                  
                                  

                                  $pw entspricht der Benutzereingabe per Formular. $testpw somit das zu prüfende Passwort.

                                  Die Prüfung funktioniert. Wenn $testpw und der hash von $pw durch die die password_verify Funktion gejagt werden, passt es wenn $pw = $testpw, bzw. passt nicht wenn $pw <> $testpw.

                                  Wenn sich salt ändert, ändert sich doch auch der Hash, korrekt? Dann kann ich ja nicht mit einem Random Salt arbeiten. Das kapiere ich nicht.

                                  LG Paul

                                  1. Tach!

                                    Wenn sich salt ändert, ändert sich doch auch der Hash, korrekt?

                                    Der Salt-Wert ist in dem Hash eingearbeitet. password_verify() kann den daraus extrahieren und damit die Eingabe hashen, um dann das Ergebnis zu vergleichen.

                                    Dann kann ich ja nicht mit einem Random Salt arbeiten.

                                    Doch, aber nur beim Hash-Erstellen. password_verify() macht dann schon alles richtig.

                                    Übrigens ist es nicht notwendig, den Salt-Wert selbst zu erstellen und das PHP-Handbuch rät auch davon ab. password_hash() hat eine eingebaute Salt-Erzeugung, die es verwendet, wenn du kein Salt übergibst.

                                    dedlfix.

                                  2. Du musst Dich bei aktuellen Methoden [ password_hash() / password_verify() ] um den Salt gar nicht kümmern. Das machen sozusagen andere für Dich.

                                    Wenn Du Dir das Beispiel angesehen hättest, dann hättest Du gesehen, dass die Hilfsfunktion für die Erzeugung eines Salt nur für crypt() und Apache-MD5 notwendig ist. Übrigens, wenn Du das binäre Hilfsprogramm htpasswd mal anschaust und benutzt:

                                    htpasswd -nbB foo GeHeim - dann kommt ab Apache 2.4 etwas wie

                                    foo:$2y$05$GRnDYvydQpyX2yNF6yqByej4gZ8JHyixOlbo7pgd468yrFCvLFIX6

                                    heraus.  Erhöht man die Rundenzahl ("Kosten") auf 2^10=1024:

                                    htpasswd -nbB -C 10 foo GeHeim foo:$2y$10$uJBSt4P3JLFHAagMWuBhWuB14QfCtCvjO0s0r5cl1kBKoCGN1fSEy

                                    foo ist der Benutzer...

                                    Die PHP-Funktion password_hash('GeHeim') liefert:

                                    $2y$10$ztCfKHQF1u.90ubdtbApYunjcR7gG2EFZaUjZMGPZ7mnH5puQlVvi

                                    Deshalb geht ab apache 2.4 auch sowas:

                                    <?php
                                    $password="geHeim";
                                    $Kosten=6; # Werte von (4 ...31)
                                    # Vorsicht: Mit 2^31=2.147.483.648 Runden kann das eine ganze Weile dauern...]
                                    
                                    # Passwort mit htpasswd hashen:
                                    $s='htpasswd -nbB -C '. $Kosten . ' foo ' . escapeshellarg($password);
                                    # htpasswd -nbB -C 6 foo "geheim"
                                    
                                    $line=trim(`$s`);
                                    
                                    $a=explode(':', $line, 2);
                                    $password_hash=$a[1];
                                    echo $password_hash, "\n";
                                    
                                    # Hash mit PHP-Funktion password_verify testen:
                                    if ( password_verify($password, $password_hash) ) {
                                      echo "verifiziert\n";
                                    } else {
                                      echo "SHIT HAPPENS\n";
                                    }
                                    
                                    

                                    Das ist dann einer Gründe dafür, , gut bekannte und fertige Funktionen zu benutzen. Hat man aber früher mal alte, mit der Apache-MD5-Methode gehashte Passwörter erzeugt und muss die weiter benutzen, dann versagt die PHP-Funktion password_verify():

                                    Man kann es dann so machen wie ich in dem Beispiel. Und natürlich sollte man dann die Benutzer darauf hinweisen, dass die das Passwort wechseln sollen, weil es bisher auf eine Weise gespeichert ist, die künftig nicht mehr als sicher gilt.

                                    Jörg Reinholz

                                    1. Letzter Anlauf. Dann gebe ich auf.

                                      In meiner mysql-DB liegt zu dem Benutzer FOO ein Passwort-Hash: $2y$06$XOLFU1iAxuEgLQdtKXVM5umb.6//rSTcZ3w7/HxwypRZwPPG8eDdO

                                      Ich suche in der mysql-DB nun einen Benutzer FOO UND PASSWORT.

                                      
                                      
                                      $daszuhashendePW = trim($_POST['password']);
                                      $options = [
                                          'cost' => 6,
                                      ];
                                      
                                      $username = 'FOO';
                                      $password = password_hash($daszuhashendePW , PASSWORD_DEFAULT, $options); 	
                                      
                                      
                                      $query = "SELECT * FROM user WHERE username = :USERNAME AND password = :PASSWORD LIMIT 1";
                                      $stmt = $pdo->prepare($query);
                                      $stmt->bindValue(":USERNAME", $username, PDO::PARAM_STR);
                                      $stmt->bindValue(":PASSWORD", $password, PDO::PARAM_STR);	
                                      $stmt->execute();
                                      
                                      if($stmt->rowCount() == 1){
                                          # Passwort OK!
                                      }
                                      else{
                                          # Passwort nicht OK!
                                      }
                                      
                                      

                                      Korrekt so?

                                      LG Paul

                                      1. Letzter Anlauf. Dann gebe ich auf.

                                        In meiner mysql-DB liegt zu dem Benutzer FOO ein Passwort-Hash: $2y$06$XOLFU1iAxuEgLQdtKXVM5umb.6//rSTcZ3w7/HxwypRZwPPG8eDdO

                                        Ich suche in der mysql-DB nun einen Benutzer FOO UND PASSWORT.

                                        NEIN!

                                        Du holst mit dem Benutzername das gehashte Passwort aus der Datenbank und (Das schreibe ich jetzt übrigens ungefähr das dritte oder vierte Mal!) vergleichst DANACH mit

                                        password_verify($übertragenes_Passwort, $gehashtes_Passwort_aus_DB)

                                        Jörg Reinholz

                                        1. 
                                          $username = trim($_POST['username']);
                                          $password = trim($_POST['password']);
                                          	
                                          $query = "SELECT * FROM user WHERE username = :USERNAME LIMIT 1";
                                          $stmt = $pdo->prepare($query);
                                          $stmt->bindValue(":USERNAME", $username, PDO::PARAM_STR);	
                                          $stmt->execute();
                                          		
                                          if($stmt->rowCount() == 1){
                                          	$result = $stmt->fetch(PDO::FETCH_ASSOC);
                                          	if(password_verify($password, $result['password'])){
                                          	   echo 'Passwort ok';
                                          	}
                                          	else{
                                          	   $message = '<p>' . LOGIN_INCORRECT . '</p>';
                                          	}	
                                          }
                                          else{
                                             $message = '<p>' . LOGIN_INCORRECT . '</p>';
                                          }
                                          
                                          

                                          Herr Reinholz,

                                          so wird ein Schuh daraus? :/

                                          LG Paul

                                          1. [code lang=php] $username = trim($_POST['username']); $password = trim($_POST['password']);

                                            Besser. Prüfe aber vorher, ob $_POST['username'] und $_POST['password'] existieren ... if( isset($_POST['username']) ) ... und nicht leer sind.

                                            $query = "SELECT * FROM user WHERE username = :USERNAME LIMIT 1";

                                            Den Stern nicht verwenden. Du willst username und password. Teile das der Datenbank auch mit und teile es damit gleichzeitig Dir als Programmierer mit. Du wirst noch lernen, warum das vorteilhaft ist...

                                            echo 'Passwort ok'; $message = '<p>' . LOGIN_INCORRECT . '</p>';

                                            An den Stellen willst Du vermutlich im endgültigen Programm entweder einen Flag setzen ($bolLoginVerified=true|false) und später auswerten oder Funktionen aufrufen, die den Rest regeln. Ich würde im Falle eines nicht gelungenen Logins z.B. das Formular anzeigen und den übertragenen Benutzername gleich wieder eintragen

                                            Jörg Reinholz

                                            1. [code lang=php] $username = trim($_POST['username']); $password = trim($_POST['password']);

                                              Besser. Prüfe aber vorher, ob $_POST['username'] und $_POST['password'] existieren ... if( isset($_POST['username']) ) ... und nicht leer sind.

                                              $query = "SELECT * FROM user WHERE username = :USERNAME LIMIT 1";

                                              Den Stern nicht verwenden. Du willst username und password. Teile das der Datenbank auch mit und teile es damit gleichzeitig Dir als Programmierer mit. Du wirst noch lernen, warum das vorteilhaft ist...

                                              echo 'Passwort ok'; $message = '<p>' . LOGIN_INCORRECT . '</p>';

                                              An den Stellen willst Du vermutlich im endgültigen Programm entweder einen Flag setzen ($bolLoginVerified=true|false) und später auswerten oder Funktionen aufrufen, die den Rest regeln. Ich würde im Falle eines nicht gelungenen Logins z.B. das Formular anzeigen und den übertragenen Benutzername gleich wieder eintragen

                                              Jörg Reinholz

                                              Ich werde es umsetzen. Nochmals vielen Dank für die starken Nerven. Mein Problem ist das meine Englisch Kenntnisse eher schlecht sind.

                                              :/

                                              LG Paul

                                            2. Moin

                                              
                                              
                                              > > $username = trim($_POST['username']);
                                              > > $password = trim($_POST['password']);
                                              > 
                                              > Besser. Prüfe aber vorher, ob $_POST['username'] und $_POST['password'] existieren ... if( isset($_POST['username']) ) ... und nicht leer sind.
                                              
                                              wäre hie rnicht besser mit empty zu prüfen?
                                              
                                              [code lang=php]
                                              if (!empty($_POST['username']) && !empty($_POST['password']))
                                              
                                              

                                              da würde automatisch auf Isset und auf ein Vorhandensein geprüft

                                              Gruß Bobby

                                              --
                                              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                                              1. Moin!

                                                Moin

                                                
                                                
                                                > > > $username = trim($_POST['username']);
                                                > > > $password = trim($_POST['password']);
                                                > > 
                                                > > Besser. Prüfe aber vorher, ob $_POST['username'] und $_POST['password'] existieren ... if( isset($_POST['username']) ) ... und nicht leer sind.
                                                > 
                                                > wäre hie rnicht besser mit empty zu prüfen?
                                                
                                                empty() ist bei so vielen Dingen "empty", die man nicht als empty bezeichnen würde, das geht auf keine Kuhhaut.
                                                
                                                Beispielsweise ist der String "0" empty. Und das ist eindeutig falsch, denn er enthält ja ein Zeichen.
                                                
                                                
                                                > [code lang=php]
                                                > if (!empty($_POST['username']) && !empty($_POST['password']))
                                                > 
                                                
                                                

                                                da würde automatisch auf Isset und auf ein Vorhandensein geprüft

                                                Ich halte Abstand von empty() - Formulardatenvalidierung ist nicht so schwer hinzukriegen - dafür gibts existierende Bibliotheken, die das viel besser hinkriegen, als es manuell hinzufummeln.

                                                - Sven Rautenberg

                                                1. Tach!

                                                  empty() ist bei so vielen Dingen "empty", die man nicht als empty bezeichnen würde, das geht auf keine Kuhhaut. Beispielsweise ist der String "0" empty. Und das ist eindeutig falsch, denn er enthält ja ein Zeichen.

                                                  Kommt auf den Kontext an. Wenn "0" in meinem Fall (zum Beispiel ein Wert in $GET/$_POST) keinen gültigen Wert repräsentieren kann, dann sehe ich empty() nicht grundsätzlich ablehenswert an.

                                                  Ich halte Abstand von empty() - Formulardatenvalidierung ist nicht so schwer hinzukriegen - dafür gibts existierende Bibliotheken, die das viel besser hinkriegen, als es manuell hinzufummeln.

                                                  Man möchte sich ja auch weiterbilden und Anfänger sollen es ja gleich "richtig machen". Wie lautet also deine Empfehlung?

                                                  dedlfix.

                                                  1. Moin!

                                                    Tach!

                                                    empty() ist bei so vielen Dingen "empty", die man nicht als empty bezeichnen würde, das geht auf keine Kuhhaut. Beispielsweise ist der String "0" empty. Und das ist eindeutig falsch, denn er enthält ja ein Zeichen.

                                                    Kommt auf den Kontext an. Wenn "0" in meinem Fall (zum Beispiel ein Wert in $GET/$_POST) keinen gültigen Wert repräsentieren kann, dann sehe ich empty() nicht grundsätzlich ablehenswert an.

                                                    Wenn ich als Leser von Code darüber nachdenken muss, ob die vielfältigen "Nebenwirkungen" von empty() eventuell vom Programmierer in Betracht gezogen wurden, oder aber die Gefahr besteht, dass sie unerwünscht sind, dann lese ich schlechten Code, der seine Intention nicht gut kommuniziert.

                                                    Bei Formularvalidierung von erforderlichen Feldern ist das hier viel sinnvoller:

                                                    if (isset($_POST['foo']) && $_POST['foo'] !== "") {
                                                        // vorhanden und kein Leerstring - damit machen wir jetzt was
                                                    }
                                                    

                                                    Im Vergleich dazu:

                                                    if (!empty($_POST['foo'])) {
                                                        // welche Inhalte von foo werden wohl dazu führen, hier reinzuspringen?
                                                    }
                                                    

                                                    Beide Varianten kranken daran, dass sie auch Arrays akzeptieren würden, aber die Empty-Variante würde, wie erwähnt, den String "0" eben auch nicht als Inhalt durchlassen.

                                                    Wenn man sowas explizit nicht will, sollte man das explizit in den Code reinschreiben.

                                                    Ich halte Abstand von empty() - Formulardatenvalidierung ist nicht so schwer hinzukriegen - dafür gibts existierende Bibliotheken, die das viel besser hinkriegen, als es manuell hinzufummeln.

                                                    Man möchte sich ja auch weiterbilden und Anfänger sollen es ja gleich "richtig machen". Wie lautet also deine Empfehlung?

                                                    Nun ja, Frameworks bieten zur Validierung von Formularen grundsätzlich was an - daran sollte man sich bedienen, wenn man eines benutzt.

                                                    Es gibt bei packagist.org außerdem zahlreiche Standalone-Bibliotheken, die man nutzen kann, beispielsweise siriusphp/validation.

                                                    - Sven Rautenberg

                                                    1. Moin!

                                                      Nun ja, Frameworks bieten zur Validierung von Formularen grundsätzlich was an - daran sollte man sich bedienen, wenn man eines benutzt.

                                                      Mal ganz ehrlich. Es geht hier im konkreten Fall nur darum, bei leeren Formulardaten nicht lange rumzurechnen.

                                                      Wenn da jetzt einer zu verarschen versucht, in dem er sich viel Mühe gibt um Arrays zu übermitteln, dann erntet er eben bestenfalls die Auskunft, dass das nicht geklappt hat. Größere Validierungsgeschichten kann man sich also völlig sparen, eine Bibliothek, welche die Daten vorher unter jedem Aspekt prüft ist schlicht Overkill.

                                                      Jörg Reinholz

                                                    2. Tach!

                                                      Wenn ich als Leser von Code darüber nachdenken muss, ob die vielfältigen "Nebenwirkungen" von empty() eventuell vom Programmierer in Betracht gezogen wurden, oder aber die Gefahr besteht, dass sie unerwünscht sind, dann lese ich schlechten Code, der seine Intention nicht gut kommuniziert.

                                                      Wenn ich als Leser von Empfehlungen selbst nachprüfen muss, welche der vielen Pakete vom Empfehler in Betracht gezogen würden, oder die Gefahr besteht, dass ich ein unbrauchbares erwische, dann lese ich eine schlechte Empfehlung, mit der das eigenen Wissen nicht gut kommuniziert wird.

                                                      Es gibt bei packagist.org außerdem zahlreiche Standalone-Bibliotheken, die man nutzen kann, beispielsweise siriusphp/validation.

                                                      Der erste Blick: "Grmpf! - Stringly typed!" Wenn Aktionen und Feldnamen nicht als Bezeichner sondern als Strings zu notieren sind, gehe ich Gefahr, dass ich mich unbemerkt vertippe. Ich muss die genaue Schreibweise erlernen, wissen oder nachschauen und kann sie nicht zeitsparend und fehlerreduzierend autovervollständigen lassen. Da ist mir ja fast noch empty() die größere Hilfe. Und die Tools meiner IDE (PhpStorm) können mir beim Refactoring nicht oder nur wenig behilflich sein, weil sie nicht wissen können, ob gleiche Strings die gleiche Bedeutung haben.

                                                      dedlfix.

                                                      1. Moin!

                                                        Tach!

                                                        Wenn ich als Leser von Code darüber nachdenken muss, ob die vielfältigen "Nebenwirkungen" von empty() eventuell vom Programmierer in Betracht gezogen wurden, oder aber die Gefahr besteht, dass sie unerwünscht sind, dann lese ich schlechten Code, der seine Intention nicht gut kommuniziert.

                                                        Wenn ich als Leser von Empfehlungen selbst nachprüfen muss, welche der vielen Pakete vom Empfehler in Betracht gezogen würden, oder die Gefahr besteht, dass ich ein unbrauchbares erwische, dann lese ich eine schlechte Empfehlung, mit der das eigenen Wissen nicht gut kommuniziert wird.

                                                        Wir bewegen uns, zumindest bei dem Beispielcode hier im Thread bzw. auch im Wiki, auf niedrigem PHP-Niveau mit ganz wenig OOP. Da kann ich kaum guten Gewissens \Zend\Form empfehlen (zu viele Abhängigkeiten, zu komplex für den Nichtnutzer der Zend-Komponenten. Dasselbe gilt für Symfony, Laravel, ...

                                                        Es gibt bei packagist.org außerdem zahlreiche Standalone-Bibliotheken, die man nutzen kann, beispielsweise siriusphp/validation.

                                                        Der erste Blick: "Grmpf! - Stringly typed!" Wenn Aktionen und Feldnamen nicht als Bezeichner sondern als Strings zu notieren sind, gehe ich Gefahr, dass ich mich unbemerkt vertippe. Ich muss die genaue Schreibweise erlernen, wissen oder nachschauen und kann sie nicht zeitsparend und fehlerreduzierend autovervollständigen lassen. Da ist mir ja fast noch empty() die größere Hilfe. Und die Tools meiner IDE (PhpStorm) können mir beim Refactoring nicht oder nur wenig behilflich sein, weil sie nicht wissen können, ob gleiche Strings die gleiche Bedeutung haben.

                                                        Alle Validator-Regeln sind als Konstanten in der Klasse \Siriusphp\Validation\Validator verfügbar. Für die Feldnamen bist du selbst als Entwickler verantwortlich. Und die einzelnen Regeln der Validierung implementiert man besser selbst in einer eigenen Klasse mit einem Namen, der dem Nutzungskontext entspricht, also beispielsweise "class UsernameLength extends AbstractValidator", anstatt dass man an jeder Stelle, wo man einen Usernamen validieren möchte, sich die einzelnen Parameter der Prüfung wieder kopiert.

                                                        Außerdem bist du mit deiner IDE kein Maßstab - jedenfalls dann nicht, wenn ich mir wie besagt den Code der Beispiele ansehe.

                                                        - Sven Rautenberg

                                                2. Moin

                                                  empty() ist bei so vielen Dingen "empty", die man nicht als empty bezeichnen würde, das geht auf keine Kuhhaut.

                                                  Und das ist auch gut so: 0, 0.0, "", false, null, array() wird neben Isset() geprüft.

                                                  Bei Formulareingaben halte ich das schon für Sinnvoll. Damit umgeht man eventuelle Probleme wegen der losen Datentypbindung wenn man nicht mit Äquivalenz prüft. Deshalb stimme ich dir mal nicht zu.

                                                  Beispielsweise ist der String "0" empty. Und das ist eindeutig falsch, denn er enthält ja ein Zeichen.

                                                  
                                                  
                                                  > > if (!empty($_POST['username']) && !empty($_POST['password']))
                                                  > > 
                                                  
                                                  

                                                  da würde automatisch auf Isset und auf ein Vorhandensein geprüft

                                                  Ich halte Abstand von empty() - Formulardatenvalidierung ist nicht so schwer hinzukriegen - dafür gibts existierende Bibliotheken, die das viel besser hinkriegen, als es manuell hinzufummeln.

                                                  Es geht ja erstmal im ersten Schritt darum obn Passwort und Username angegeben wurde. Und das ist mit emppty in meinen Augen besser zu prüfen. Das weitergehende Validierungen vorgenommen werden müssen, ist klar. HAt aber mit dem Thema des Prüfens auf Vorhandensein nix zu tun.

                                                  Gruß Bobby

                                                  --
                                                  -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                                                  1. Moin!

                                                    Moin

                                                    empty() ist bei so vielen Dingen "empty", die man nicht als empty bezeichnen würde, das geht auf keine Kuhhaut.

                                                    Und das ist auch gut so: 0, 0.0, "", false, null, array() wird neben Isset() geprüft.

                                                    Bei Formulareingaben halte ich das schon für Sinnvoll. Damit umgeht man eventuelle Probleme wegen der losen Datentypbindung wenn man nicht mit Äquivalenz prüft. Deshalb stimme ich dir mal nicht zu.

                                                    "0" wäre ein gültiger Username oder ein gültiges Passwort, genau wie "1". Außer wenn Zahlen grundsätzlich nicht erlaubt wären, und Passworte länger als ein Zeichen sein müssen.

                                                    Außerdem kann man auch ein nichtleeres Array in $_POST['username'] schicken, und das würde durchgehen.

                                                    Validierung auf die notwendigen, sinnvollen Werte, die man fordern will, ist also sowieso in größerem Umfang notwendig.

                                                    Es geht ja erstmal im ersten Schritt darum obn Passwort und Username angegeben wurde. Und das ist mit emppty in meinen Augen besser zu prüfen. Das weitergehende Validierungen vorgenommen werden müssen, ist klar. HAt aber mit dem Thema des Prüfens auf Vorhandensein nix zu tun.

                                                    Wenn ich prüfen will, ob ich auf einen Array-Schlüssel zugreifen kann, ist isset() die simpelste Variante, sofern ich NULL im Array ebenfalls als nicht existent ansehe (isset() ist auch bei NULL false).

                                                    Validierung kommt in die Validierung - und eigentlich gehört das Checken, ob ein Formularwert überhaupt gesendet wurde, mit in die Validierung rein, da prüfe ich nichts vorab mit isset().

                                                    - Sven Rautenberg

                                                    1. Moin!

                                                      "0" wäre ein gültiger Username oder ein gültiges Passwort, genau wie "1". Außer wenn Zahlen grundsätzlich nicht erlaubt wären, und Passworte länger als ein Zeichen sein müssen.

                                                      Validierung auf die notwendigen, sinnvollen Werte, die man fordern will, ist also sowieso in größerem Umfang notwendig.

                                                      Nein, ist sie hier nicht. Die endgültige Validierung wird definitiv durch den Abgleich mit der Benutzerdatenbank vorgenommen. Alles, was vorher stattfindet, ist lediglich eine und ganz bewusst eine einfache(!) Prüfung um bei leeren Eingaben nicht erst das ganze System anzuwerfen, Dateien zu lesen oder Datenbanken zu befragen und ergo eine Menge Prozessortakte zu verbraten.

                                                      Außerdem kann man auch ein nichtleeres Array in $_POST['username'] schicken, und das würde durchgehen.

                                                      Die Prüfung mit if isset() soll vor allem verhindern, dass die Prüfung gegen den leeren String eine Notiz schmeißt. Wenn aller hundert Jahre jemand hingeht und meint, mit allerhand Aufwand einen Array senden zu müssen um mit seinem Datenmüll bei isset() noch durchzukommen, dann mag er sich an der Notiz einen runterh... Pardon: an der selben goutieren.

                                                      Angemeldet wird er damit nicht und ich habe die genannten hundert Jahre lang keinen Prozessortakt und auch keine Mikrowattmillisekunde darauf verschwendet, auf jeden denkbaren Unsinn zu prüfen.

                                                      Jörg Reinholz

                                                    2. Moin

                                                      "0" wäre ein gültiger Username oder ein gültiges Passwort, genau wie "1". Außer wenn Zahlen grundsätzlich nicht erlaubt wären, und Passworte länger als ein Zeichen sein müssen.

                                                      Außerdem kann man auch ein nichtleeres Array in $_POST['username'] schicken, und das würde durchgehen.

                                                      Validierung auf die notwendigen, sinnvollen Werte, die man fordern will, ist also sowieso in größerem Umfang notwendig.

                                                      lies nochmal meinen Beitrag richtig. Ich sagte dass natürlich noch eine validierung stattfinden muss. mit !empty prüfe ich aber VOR dieser Validierung bereits mehr ungültige Fälle als mit isset, und muss so nicht erst in die Validierung springen! Jetzt verstanden?

                                                      Gruß Bobby

                                                      --
                                                      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                                  3. $options = [     'salt' => '1234567890abcdefghijklmnopqrstuvwxyz', ];

                                    $hash = password_hash($pw, PASSWORD_DEFAULT, $options);

                                    HALT: Das ist FALSCH!

                                    Damit erleichterst Du es einem Angreifer, der die Datenbank erbeutet hat, die Passwörter zu extrahieren, denn der muss nur einmal hingehen und die Rainbow.Tables für Deinen konstanten Salt erzeugen.

                                    Richtig ist, den salt NICHT vorzuschreiben, denn dann nimmt password_hash() jedes Mal einen zufälligen und der Angreifer muss für jedes Passwort neue Rainbow-Tables erzeugt und gespeichert haben. Zumindest das Speichern ist derzeit nicht möglich, denn:

                                    64 mögliche Zeichen im Salt und 16 Stellen im Salt ergeben schlappe 64^16=79.228.162.514.264.337.593.543.950.336 verschiedene Möglichkeiten für den Salt!

                                    Jörg Reinholz

                            2. Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                              Moin dedfix,

                              password_hash() steht in dem Beispiel mit drin und wird preferiert.

                              Jörg Reinholz

                              1. Moin!

                                Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                                Moin dedfix,

                                password_hash() steht in dem Beispiel mit drin und wird preferiert.

                                Ja, aber nur beim Hashen - beim Prüfen passiert vor dem password_verify noch viel Zeugs, dass ich auf den ersten Blick nicht verstehe und deshalb nicht gewillt bin, weiter zu untersuchen.

                                Außerdem erscheint es mir grandios eklig, dass der Aufruf der Hash-Funktion eventuell mit header(); exit(); das Skript abbricht!

                                Zum einen: Eine Hash-Funktion hat nicht das Skript zu killen! Zum zweiten: Eine Hash-Funktion hat nicht anzunehmen, dass man in einem HTTP-Kontext ist und deshalb sowas wie "Header" ausgeben kann. Oder WENN man in einem HTTP-Kontext ist, dass man NOCH Header ausgeben kann.

                                Es gibt die Kompatibilitätsbibliothek von ircmaxell, und die sollte man nehmen - oder auf PHP 5.5 oder höher aktualisieren.

                                - Sven Rautenberg

                                1. Moin!

                                  Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                                  Moin dedfix,

                                  password_hash() steht in dem Beispiel mit drin und wird preferiert.

                                  Ja, aber nur beim Hashen - beim Prüfen passiert vor dem password_verify noch viel Zeugs, dass ich auf den ersten Blick nicht verstehe und deshalb nicht gewillt bin, weiter zu untersuchen.

                                  Jaja. Im Wiki-Beitrag habe ich neue Erkenntnisse verarbeitet- da geht jetzt einiges deutlich kürzer:

                                  $test = crypt($klartext, $hash)

                                  liefert (wenn der Algo unterstützt wird) den hash, so dass Passwörter gleich so geprüft werden können:

                                  if ( $hash == crypt($klartext, $hash) ) {    "Ha! Drin!" } else {    "Zu blöd, ein Passwort zu tippen?" }

                                  Außerdem erscheint es mir grandios eklig, dass der Aufruf der Hash-Funktion eventuell mit header(); exit(); das Skript abbricht!

                                  Das ist Geschmackssache. Dazu steh in den style-guides des Bestellers was - oder eben nicht. Was das Programmieren betrifft: Ich für meinen Teil sehe da sofort - "weg, Abbruch, Ende". Und halte es für sicherer als weiter unten ständig zu prüfen, ob ein flag gesetzt ist.

                                  Jörg Reinholz

                            3. Hi,

                              Die derzeitige Empfehlung für PHP lautet ab Version 5.5 password_hash().

                              Und für Versionen ab 5.3.7 password_compat, auch bei composer zu finden: password_compat bei packagist.

                              Bitte nutze keine Eigenentwicklung, sondern eine weltweit geprüfte.

                              Bis die Tage, Matti

                        2. Moin,

                          in etwa so:

                          
                          
                          echo '<p>';
                          $string = 'test';
                          $salz = 'salt';
                          
                          for ($i = 0; $i< 5; $i++){
                          	echo '<p>'.$string=crypt($salz.$string).'</p>';
                          }
                          echo '</p>';
                          
                          
                          

                          Der Hash des Benutzers in der DB sollte wie gespeichert werden? Mit dem "Salz" gehashed oder ohne? Den das Salz jedes Benutzers darf sich ja nicht ändern. Sonst wird der Vergleich ja immer in die "Hose" gehen.

                          LG Paul

                          1. Der Hash des Benutzers in der DB sollte wie gespeichert werden?

                            So wie ihn die jeweils benutzte Funktion zurück gibt. Der Salt ist da schon mit drin. Was die Funktionen (jenseits von purem sha1 oder md5 zurück geben sieht ungefähr so aus:

                            $METHODE$rounds=RUNDEN$SALT$HASH   oder, je nach Verfahren

                            Das ist wie CSV: Die $ dienen als Trennzeichen.

                            Bei Methoden mit fest stehender Rundenzahl entfällt $rounds=RUNDEN.

                            Beim verifizieren musst Du aber anders vorgehen: Du musst den hash mitsamst dem Salt erst aus der Datenbank holen und dann das Passwort verifizieren. Erst wenn das funktionierte kannst Du "den Benutzer reinlassen".

                            Mit der derzeit aktuellen Methode würde das so aussehen:

                            <?php
                            $password="geHeim";
                            $password_hash=password_hash($password, PASSWORD_DEFAULT);
                            echo $password_hash, "\n";
                            
                            if ( password_verify($password, $password_hash) ) {
                              echo "verifiziert\n";
                            }
                            
                            
          2. Was bedeutet "salzen"?

            Für Dein Skript vor allem:

            • Deine Prüfungen auf die Eingabe
            • Du versuchst das mehrfach gesalzene und gehashte Passwort aus der Datenbank zu holen.
            • Wenn es den user nicht gibt -> abweisen
            • Sonst: eingegebenes Passwort verifizieren (läuft darauf hinaus, dass es eenfalls mehrfach gesalzen und gehasht wird)
            • Falls nicht ok -> abweisen Falls doch ... weiter wie nach Deinem Test.
      2. Besser sha1?

        Auf keinen Fall!

        Jörg Reinholz

  2. http://schwalbennest.unwichdsch.de/

    Die URL zum anschauen, testen. : )

    1. Hi,

      http://schwalbennest.unwichdsch.de/

      Die URL zum anschauen, testen. : )

      Aha, so sieht also ein 403 Forbidden nach einem 401 Unauthorized aus.

      MfG ChrisB

      --
      Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
      1. Entschuldigung,

        da lag noch eine htaccess File "rum". : )

        LG Paul

  3. Moin,

    Mal angenommen, ein Kunde wünscht nach der Anmeldung eine Begrüßung, welche den Namen, ggf. die Benutzergruppe und den Zeitpunkt der Anmeldung ausgeben soll, wie würdest Du das erweiteren?

    Schöne Grüße.

    1. Guten Morgen,

      wobei einen guten Tag kann durchaus auch bereits gewünscht werden.

      Mal angenommen, ein Kunde wünscht nach der Anmeldung eine Begrüßung, welche den Namen, ggf. die Benutzergruppe und den Zeitpunkt der Anmeldung ausgeben soll, wie würdest Du das erweiteren?

      Dann würde ich den Namen aus der DB in der einer $_SESSION Variable speichern.

      LG Paul

      1. Mahlzeit;

        wobei einen guten Tag kann durchaus auch bereits gewünscht werden.

        Mal angenommen, ein Kunde wünscht nach der Anmeldung eine Begrüßung, welche den Namen, ggf. die Benutzergruppe und den Zeitpunkt der Anmeldung ausgeben soll, wie würdest Du das erweiteren?

        Dann würde ich den Namen aus der DB in der einer $_SESSION Variable speichern.

        Ok ;)

        Kommen wir zu einem weiteren Punkt womit der Code leserlicher und aufgewertet wird: Eine Funktion welche die Userdaten aus der DB ermittelt, das bedeutet:

        1. SQL-Statements fliegen raus aus Deinem Code
        2. des Gleichen sind die Credentials zum DB-Zugang raus aus dem Code
        3. es wird nur noch eine Funktion aufgerufen   3a) ggf. eine Methode mit vorheriger Erstellung einer Instanz der Klasse User (OOP-Style)
        4. einfacher Griff in ein Array welches die Funktion/Methode bei (3) zurückliefert.

        Wie wärs damit?

        Schöne Grüße.

        1. ...

          Wie wärs damit?

          Klingt super. Aber erst nachdem ich mich mit dem "salzen" auseinandergesetzt habe.

          :/

          LG Paul

  4. Ich habe den passenden Wiki-Artikel ergänzt.

    In der Überschrift des TO steht:

    "Verbesserungen, Kritik, Meinungen"

    Wer will und kann soll aber auch gleich den Artikel besser machen :)

    Jörg Reinholz

    1. Om nah hoo pez nyeetz, Jörg Reinholz!

      Ich habe den passenden Wiki-Artikel ergänzt. Wer will und kann soll aber auch gleich den Artikel besser machen :)

      Ich befürchte, es ist teilweise doppelte Arbeit gemacht worden. http://wiki.selfhtml.org/wiki/Benutzer:Suit/Loginsystem_und_Benutzerregistrierung_mit_PHP_und_MySQL

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Garn und Garnison. http://www.billiger-im-urlaub.de/kreis_sw.gif
      1. Ich befürchte, es ist teilweise doppelte Arbeit gemacht worden. http://wiki.selfhtml.org/wiki/Benutzer:Suit/Loginsystem_und_Benutzerregistrierung_mit_PHP_und_MySQL

        Ja. Der müsste wohl auch angepasst werden... steht noch bei crypt();

        1. Om nah hoo pez nyeetz, Jörg Reinholz!

          Ich befürchte, es ist teilweise doppelte Arbeit gemacht worden. http://wiki.selfhtml.org/wiki/Benutzer:Suit/Loginsystem_und_Benutzerregistrierung_mit_PHP_und_MySQL

          Ja. Der müsste wohl auch angepasst werden... steht noch bei crypt();

          Vor allem müsste es ein Artikel werden.

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Böll und Böller. http://www.billiger-im-urlaub.de/kreis_sw.gif
          1. Vor allem müsste es ein Artikel werden.

            Aber heute nicht mehr. Und was wohl suit dazu sgaen würde?

            Auch befürchte ich, dass für die Leser alles auf einmal (Passwörter unter Berücksichtigung alter PHP-Installationen hashen und Speichern in Datenbank ein wenig zu viel wird...

            Diskussion? Meinungen hierzu?

    2. Om nah hoo pez nyeetz, Jörg Reinholz!

      Ich habe den passenden Wiki-Artikel ergänzt.

      Vielen Dank für dein Engagement.

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Sandal und Sandalette. http://www.billiger-im-urlaub.de/kreis_sw.gif
    3. Ich habe den passenden Wiki-Artikel ergänzt.

      Der Unterschied zwischen .htaccess und einem Login-System sollte besser verdeutlicht werden.

      .htaccess:   URLs bekommen eine Zugangskontrolle, die Autentifizierung ist an den URL gebunden Loginsystem: INHALTe bekommen eine Zugangskontrolle, Inhalte sind vom URL unabhängig

      Mit einem Loginsystem kann weiter unterschieden werden zwischen Autentifizierung und Autorisierung: Ein Benutzer autentifiziert sich, das ist der Login. Nach dem Login stehen dem Benutzer Inhalte zur Verfügung, für die er autorisiert ist.

      Schöne Grüße.

      1. Ich habe den passenden Wiki-Artikel ergänzt. Der Unterschied zwischen .htaccess und einem Login-System sollte besser verdeutlicht werden.

        Der wissende Leser mag erahnen, worauf Du hinaus willst.

        .htaccess:   URLs bekommen eine Zugangskontrolle, die Autentifizierung ist an den URL gebunden Loginsystem: INHALTe bekommen eine Zugangskontrolle, Inhalte sind vom URL unabhängig Mit einem Loginsystem kann weiter unterschieden werden zwischen Autentifizierung und Autorisierung: Ein Benutzer autentifiziert sich, das ist der Login. Nach dem Login stehen dem Benutzer Inhalte zur Verfügung, für die er autorisiert ist.

        Selbst der wissende Leser (ich zumindest) hält diese Sätze mindestens für verwirrend. Jörgs Artikel hat eine einfache, nachvollziehbare Sprache. So wie es sich für einen solchen Artikel gehört. Das sollte man nicht versauen.

        1. Ich habe den passenden Wiki-Artikel ergänzt.

          Jörgs Artikel hat eine einfache, nachvollziehbare Sprache. So wie es sich für einen solchen Artikel gehört. Das sollte man nicht versauen.

          Nein, ich bin nicht der Autor des Textes. Ich habe den Artikel nur um den "kryptischen Teil" ergänzt. Mit den Texten hat sich jemand anderes viel Mühe gegeben.

          Jörg Reinholz

    4. Jörg Reinholz

    5. Moin Jörg,

      Ich habe den passenden Wiki-Artikel ergänzt.

      Hm, ich finde es nicht gut herkömmliche Hashing-Strategien zu empfehlen. Stand der Technik sind heutzutage Bcrypt, PBKDF2 oder Scrypt.

      LG,  CK

      1. Moin Jörg,

        Ich habe den passenden Wiki-Artikel ergänzt.

        Hm, ich finde es nicht gut herkömmliche Hashing-Strategien zu empfehlen.

        Stand der Technik sind heutzutage Bcrypt, PBKDF2 oder Scrypt.

        hash_pbkdf2("sha256", $password, $salt, $iterations, 20);

        Da kann ich also, und das habe ich getan, auch crypt bzw. password_hash und password_verity nehmen...

        Und was sagen die Entwickler?

        Notes: Caution The PBKDF2 method can be used for hashing passwords for storage. However, it should be noted that password_hash() or crypt() with CRYPT_BLOWFISH are better suited for password storage.

        Aha. Die sagen, ich hätte das Richtige getan.

        Jörg Reinholz

        1. Moin Jörg,

          Aha. Die sagen, ich hätte das Richtige getan.

          Du hast mich falsch verstanden ;) meine Kritik war nicht, dass du die modernen Methoden nicht anwendest, sondern dass du die alten nicht rausgeworfen hast. Vor allem das hier:

          
          if (CRYPT_MD5 == 1) {
          
          

          stört mich doch sehr. MD5 ist tot und sollte nicht mehr verwendet werden.

          LG,  CK

          1. 
            
            > if (CRYPT_MD5 == 1) {
            > 
            
            

            stört mich doch sehr. MD5 ist tot und sollte nicht mehr verwendet werden.

            Ja. Allerdings hatte ich dazu geschrieben, dass man diese Methoden nicht mehr verwenden soll. Weil es mir dann doch als verwirrend erschien habe ich das inzwischen allerdings schon rausgeworfen, das heisst, ich habe den gesamten Abschnitt gewaltig überarbeitet.

            Jörg Reinholz

            1. Moin Jörg,

              Ja. Allerdings hatte ich dazu geschrieben, dass man diese Methoden nicht mehr verwenden soll.

              Ja, aber trotzdem im Beispiel verwendet ;) Das ist ungefähr so als würde ich vegetarisches Essen predigen um dann Bratwürste auf die Liste der empfohlenen Lebensmittel zu setzen.

              Weil es mir dann doch als verwirrend erschien habe ich das inzwischen allerdings schon rausgeworfen, das heisst, ich habe den gesamten Abschnitt gewaltig überarbeitet.

              Gefällt mir viel besser, danke!

              LG,  CK