suit: Neuer Artikel (Baustelle): Loginsystem und Benutzerregistrierung

Bezugnehmen auf diesen Beitrag https://forum.selfhtml.org/?t=215336&m=1474501 habe ich ein einfaches Benutzerregistrierungs- und Loginsystem gestrickt - die Baustelle ist im Wiki im Benutzernamensraum unterhalb meiner Benutzerseite zu finden:

http://wiki.selfhtml.org/wiki/Benutzer:Suit/Loginsystem_und_Benutzerregistrierung_mit_PHP_und_MySQL

Der Text selbst ist noch in Arbeit, da der Code im Vergleich zum "Vorgänger" aber deutlich gewachsen ist, bin ich nicht sicher wie die Beschreibung aussehen soll. Sprich sollen die Ressourcen als Komplettpaket zum Download angeboten werden und der Code nur Auszutagsartig zur erläuterung im Wiki dargestellt werden oder soll hier der vollständige Code (wie derzeit) zu sehen sein und die Erklärungen dazwischen halt ausführlicher?

Unabhängig davon: bitte mal einen Blick drauf werfen, ich hab' sicher noch den ein oder anderen Fehler drin.

  1. Om nah hoo pez nyeetz, suit!

    Der Text selbst ist noch in Arbeit, da der Code im Vergleich zum "Vorgänger" aber deutlich gewachsen ist, bin ich nicht sicher wie die Beschreibung aussehen soll. Sprich sollen die Ressourcen als Komplettpaket zum Download angeboten werden und der Code nur Auszutagsartig zur erläuterung im Wiki dargestellt werden oder soll hier der vollständige Code (wie derzeit) zu sehen sein und die Erklärungen dazwischen halt ausführlicher?

    Ich bin für ein "Zerpflücken" des Codes und ausführliche Erklärungen im Wiki. Die vollständigen Ressourcen sollten auch als Text erscheinen, sodass jeder der mag sich das kopieren kann.

    Beide Varianten bieten die Gefahr der Inkonsistenz, weil man an zwei Stellen ändern muss. Dies kann im ersten Fall aber jeder tun, wo hingegen die Änderungen an der ZIP-Datei nur ausgewählte Leute vornehmen können.

    Matthias

    --
    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Pan und Panda.

    1. Ich bin für ein "Zerpflücken" des Codes und ausführliche Erklärungen im Wiki. Die vollständigen Ressourcen sollten auch als Text erscheinen, sodass jeder der mag sich das kopieren kann.

      Beide Varianten bieten die Gefahr der Inkonsistenz, weil man an zwei Stellen ändern muss. Dies kann im ersten Fall aber jeder tun, wo hingegen die Änderungen an der ZIP-Datei nur ausgewählte Leute vornehmen können.

      Zusammenfassend:
      Unten drunter alle Ressourcen im Volltext und oben nur auszugsweise als Duplikat.

      Ich hab' mal die erste Hälfe des Beschreibungstexts reinkopiert - ist noch weitgehend unformatiert - ich geh' jetzt mal einkaufen :)

      1. Tach!

        Unten drunter alle Ressourcen im Volltext und oben nur auszugsweise als Duplikat.

        Die hab ich mal teilweise geändert. Hier noch ein paar Anmerkungen, auch zu Dingen, die ich nicht geändert habe. Zum Beispiel gehört der Zeilenumbruch nach einem ?> mit zum schließenden PHP-Tag und landet nicht in der Ausgabe. Man muss also nicht

        <?php ...
        ?><!doctype ...

        schreiben, sondern kann das doctype in eine eigenen Zeile bringen. Die Zeilen sind teilweise sehr lang. Besonders ungünstig wird das auch, weil Tabulatoren im Browser als 8 Zeichen Abstand dargestellt werden. Hier wären Leerzeichen besser.

        Der typsichere Vergleich sollte da angewendet werden, wo er sinnvoll ist. Das Ergebnis von crypt() ist immer weder 0 noch false. $_SESSION['login'] wird im Script gesetzt. Ob da ein anderer Wert als true drinsteht, der einem true entspricht, ist belanglos. Deswegen kann dir Prüfung problemlos durch empty() ersetzt werden. Das gibt dann auch keine Notice-Meldungen, wenn die Session leer ist.

        Ein Location-Header will eine vollständige URL. Was ist besser daran, ./foo.ext statt foo.ext zu notieren? Gegebenenfalls sollte das erläutert werden.

        Der Teil mit dem crypt() soll später gegen eine PHP-Funktion ausgetauscht werden können, schreibst du. Dann mach das doch gleich austauschbar, pack den Code in eine Funktion.

        dedlfix.

        1. Die hab ich mal teilweise geändert. Hier noch ein paar Anmerkungen, auch zu Dingen, die ich nicht geändert habe. Zum Beispiel gehört der Zeilenumbruch nach einem ?> mit zum schließenden PHP-Tag und landet nicht in der Ausgabe. Man muss also nicht

          <?php ...
          ?><!doctype ...

          Gut zu wissen, dass wusste ich nicht.

          Ein Location-Header will eine vollständige URL. Was ist besser daran, ./foo.ext statt foo.ext zu notieren? Gegebenenfalls sollte das erläutert werden.

          Das hat keinen speziellen Grund, Gewohnheitssache.

          Der Teil mit dem crypt() soll später gegen eine PHP-Funktion ausgetauscht werden können, schreibst du. Dann mach das doch gleich austauschbar, pack den Code in eine Funktion.

          Man kann genauso in alle Ewigkeit crypt() verwenden, weil password_hash() ohnehin dasselbe tut - es gibt in PHP in dieser hinsicht leider wieder einen ziemlich Wildwuchs.

          Ich habe überlegt, das ganze in eine Funktion auszualgern, aber das macht das ganze nicht besser - wenn, dann müsste man das Ordentlich machen und password_hash() und password_verify() nachbilden, das hat aber dann ein Codemonster zur Folge, welches die Sache für einsteiger nicht grade verständlicher macht:

          https://github.com/ircmaxell/password_compat/blob/master/lib/password.php

          1. Hallo

            Der Teil mit dem crypt() soll später gegen eine PHP-Funktion ausgetauscht werden können, schreibst du. Dann mach das doch gleich austauschbar, pack den Code in eine Funktion.

            Man kann genauso in alle Ewigkeit crypt() verwenden, weil password_hash() ohnehin dasselbe tut - es gibt in PHP in dieser hinsicht leider wieder einen ziemlich Wildwuchs.

            Ich habe überlegt, das ganze in eine Funktion auszualgern, aber das macht das ganze nicht besser - wenn, dann müsste man das Ordentlich machen und password_hash() und password_verify() nachbilden, das hat aber dann ein Codemonster zur Folge, welches die Sache für einsteiger nicht grade verständlicher macht:

            https://github.com/ircmaxell/password_compat/blob/master/lib/password.php

            Reichte es nicht, in der Funktion mit function_exists('password_hash') prüfen zu lassen, ob es diese Funktion gibt, ansonsten deinen Code auszuführen und das gecryptete Passwort zurückgeben zu lassen?

            Tschö, Auge

            --
            Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
            Terry Pratchett, "Wachen! Wachen!"
            ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
            Veranstaltungsdatenbank Vdb 0.3
            1. Reichte es nicht, in der Funktion mit function_exists('password_hash') prüfen zu lassen, ob es diese Funktion gibt, ansonsten deinen Code auszuführen und das gecryptete Passwort zurückgeben zu lassen?

              Sicher würde das reichen - meine Überlegung ging aber dahin, dass durch diesen schnipsel ggf. jemand glauben könnte, dass password_hash() auch nichts anderes tut - das trifft aber nicht ganz zu :)

  2. Unabhängig davon: bitte mal einen Blick drauf werfen, ich hab' sicher noch den ein oder anderen Fehler drin.

    Verbindung zur Datenbank in eigenes Skript auslagern, dieses einbinden.
    Wird insgesamt kürzer und richtiger.

    1a)
    bei der Gelegenheit auch die Kodierung setzen.
    The character set must be set either at the server level, or with the API function mysqli_set_charset()

    Benutzernamen, Passwörter immer trimmen.
    Benutzername immer in Kleinbuchstaben;

    $query = sprintf(
    "INSERT INTO users (username, password)
    SELECT * FROM (SELECT '%s', '%s') as new_user
    WHERE NOT EXISTS (
    SELECT username FROM users WHERE username = '%s'
    ) LIMIT 1;",
    $mysqli->real_escape_string($_POST['f']['username']),
    $mysqli->real_escape_string($_POST['f']['password']),
    $mysqli->real_escape_string($_POST['f']['username'])
    );
    $mysqli->query($query);

    Hm.
    $query = 'INSERT INTO users (
    username,
    password
    ) VALUES (
    "'.$mysqli->real_escape_string($_POST['f']['username']).'",
    "'.$mysqli->real_escape_string($_POST['f']['password']).'"'
    );
    $mysqli->query($query);

    müsste reichen, denn wenn der Spalteindex unique ist, dann schmeisst mysqli einen auswertbaren Fehler. Ist für mich perfekt genug.

    L)
    Kann ich Dir meine Variante schicken (tar.gz)? Die ist zwar noch nicht perfekt, auch mit dem ungeliebten mysql- statt mysqli - funktioniert aber schon prächtig.

    Ich erweitere die gerade um eine "Passwort-vergessen-Funktion" und um eine Funktion für die Prüfung der Komplexibilität.

    Und nein. Ich benutze nicht crypt, sondern hash mit sha256 (liefert vertrauenserweckende, gegen openssl geprüfte, also in anderen Sprachen wiederholbare Ergebnisse - was mir wichtig ist) und einen Salt aus allen druckbaren ASCII-Zeichen mit einstellbarer Länge (default:32). Auch die Iterationen (default:50000) lege ich (oder der Anwender) fest.

    Jörg Reinholz

      Verbindung zur Datenbank in eigenes Skript auslagern, dieses einbinden.
      Wird insgesamt kürzer und richtiger.

      Das war eigentlich absicht um das Ganze nicht zu verstrickt zu machen und man die einzelnen Dateien als Einsteiger "greifbar" und isoliert betrachten kann - ich hab sogar schon überlegt, das ganze ohne Affenformular und ohne redirects zu bauen, damit es noch leichter nachvollziehbar ist.

      In der Praxis würde ich das ganz anders aufbauen - aber hier gehts um eine einfache Anleitung die entsprechende Grundlagen vermittelt und keine "do it perfectly"-Lösung.

      1a)
      bei der Gelegenheit auch die Kodierung setzen.
      The character set must be set either at the server level, or with the API function mysqli_set_charset()

      Hat in meinem Fall keine Rolle gespielt, darum hab' ich es ignoriert - ich bin hier bemüht das Ganze auf das Wesentliche zu beschränken.

      Benutzernamen, Passwörter immer trimmen.

      Beim Benutzer unter umständen ja, je nachdem welchen Zweck dieser hat. Wenn er ein Eindeutigkeitsmerkmal darstellt: ja, weil sonst sind Fakes mit Leerzeichen rundherum etwas einfach - da stimme ich zu. Aber diese Prüfung ist nicht Teil des Artikels, da hab' ich eh einen Absatz verfasst wo es um die Prüfung geht.

      Bei Passwörtern ist das aber ein fataler Fehler: wenn jemand absichtlich sein Passwort mit einem Leerzeichen beginnt, ist das sehr unpraktisch.

      Benutzername immer in Kleinbuchstaben;

      Wozu? Sicher nicht :)

      $query = 'INSERT INTO users (
      username,
      password
      ) VALUES (
      "'.$mysqli->real_escape_string($_POST['f']['username']).'",
      "'.$mysqli->real_escape_string($_POST['f']['password']).'"'
      );
      $mysqli->query($query);

      müsste reichen, denn wenn der Spalteindex unique ist, dann schmeisst mysqli einen auswertbaren Fehler. Ist für mich perfekt genug.

      Ja - funktionieren wird es, nur ist die Lösung sehr hölzern. Die Intention hinter der gezeigten Lösung ist, dass man hier auch komplexe Prüfungen machen kann, die man sonst mit den üblichen Feldeinstellungen nicht machen kann. Die Bedingungung im NOT-EXISTS-Zweig lässt sich nahezu beliebig anpassen.

      Zudem ist es nie eine gute Lösung sich auf einen Fehler zu verlassen - es funktioniert zwar, aber "funktionieren" ist etwas anders :)

      Kann ich Dir meine Variante schicken (tar.gz)? Die ist zwar noch nicht perfekt, auch mit dem ungeliebten mysql- statt mysqli - funktioniert aber schon prächtig.

      Schmeiss mal auf meine Mail-Adresse.

      Und nein. Ich benutze nicht crypt, sondern hash mit sha256 (liefert vertrauenserweckende, gegen openssl geprüfte, also in anderen Sprachen wiederholbare Ergebnisse - was mir wichtig ist) und einen Salt aus allen druckbaren ASCII-Zeichen mit einstellbarer Länge (default:32). Auch die Iterationen (default:50000) lege ich (oder der Anwender) fest.

      SHA-256 ist defekt, viel zu schnell und führt kein key stretching durch - für Passwörter absolut ungeeignet. Ebenso gibt es kaum vernünftige Gründe auf crypt bzw. allgemein auf Standards zu verzichten.

      Wenn in diesem beispiel bcrypt künftig nicht mehr ausreicht, muss einfach nur das Crypt-Schema umgestellt werden - alle alten Passwörter funktionieren dann trotzdem noch und alle neuen werden entsprechend stärker generiert. In deinem Fall musst du vermutlich einen Handstand machen. Das halte ich für nicht sinnvoll.

      1. Tach!

        ich bin hier bemüht das Ganze auf das Wesentliche zu beschränken.

        Wenn man sich auf das Wesentliche beschränkt, dann wird das so von den Anwendern kopiert. Und dann fehlen am Ende wesentliche Teile, wie Fehlerbehandlung und Kodierungsaushandlung.

        Es sollten auch nicht nur die wiederholt auftretenden MySQL-Routinen sondern auch die Fehlerausgabe in wiederverwendbaren Code gepackt werden. Das macht den Code kürzer und man muss im Fehlerfall nicht an mehreren Stellen korrigieren.

        Noch eins: Wenn die Datenbank nciht erreicht werden kann, ist as kein Fehler, den man dem Anwender vorwerfen muss. Es ist nicht sein Verschulden und muss anders abgefangen werden als das was durch seine (fehlerhaften) Eingaben zustande kommt.

        dedlfix.

        1. ich bin hier bemüht das Ganze auf das Wesentliche zu beschränken.

          Wenn man sich auf das Wesentliche beschränkt, dann wird das so von den Anwendern kopiert. Und dann fehlen am Ende wesentliche Teile, wie Fehlerbehandlung und Kodierungsaushandlung.

          Das ist ein gutes Argument, aber besonders so eine "einfache" geschichte wie eine Login-Routine hat sehr viele Abhängigkeiten. Allein über die sinnvolle Validierung von Formularfeldern oder die Modellierung der Datenbank könnte man Seitenweise schreiben. Ich hatte ursprünglich einige Dinge mehr drin, die ich aber dann wieder rausgestrichen habe, weil das Ganze für einen Einsteiger schon eine ziemlich unübersichtliche Dimension angenommen hat.

          Ich hab' mir zum Ziel genommen zumindest etwas Hausverstand vorauszusetzen und möchte bewusst keine Copy&Paste-fähige Lösung bereitstellen.

          Ich denke man muss hier davon ausgehen, dass der Leser zumindest weiß, wie ein Affenformular funktioniert oder wie Formularvalidierung funktioniert.

          Es sollten auch nicht nur die wiederholt auftretenden MySQL-Routinen sondern auch die Fehlerausgabe in wiederverwendbaren Code gepackt werden. Das macht den Code kürzer und man muss im Fehlerfall nicht an mehreren Stellen korrigieren.

          Das hat wie gesagt den Grund, dass man die dinge isoliert verwenden kann - ich hatte ursprünglich auch das Fehlerhandling einer anderen Lösung eingebaut, aber allein das wäre schon wieder einen Artikel für sich wert - das kann man nicht einfach unkommentiert einbauen.

          Noch eins: Wenn die Datenbank nciht erreicht werden kann, ist as kein Fehler, den man dem Anwender vorwerfen muss. Es ist nicht sein Verschulden und muss anders abgefangen werden als das was durch seine (fehlerhaften) Eingaben zustande kommt.

          Auch das ist mir bewusst - das kommt in der Erklärung noch dazu. Es werden z.B. auch "benutzername existiert nicht" oder "passwort falsch" getrennt betrachtet - das ist auch nicht grade praxistauglich.

          1. Tach!

            Es sollten auch nicht nur die wiederholt auftretenden MySQL-Routinen sondern auch die Fehlerausgabe in wiederverwendbaren Code gepackt werden. Das macht den Code kürzer und man muss im Fehlerfall nicht an mehreren Stellen korrigieren.
            Das hat wie gesagt den Grund, dass man die dinge isoliert verwenden kann -

            Will man denn das? Ich denke, dass die Mehrfachverwendbarkeit höher gewichtet werden sollte als die kopierbare Verwendung.

            dedlfix.

      2. Om nah hoo pez nyeetz, suit!

        […] und man die einzelnen Dateien als Einsteiger "greifbar" und isoliert betrachten kann - ich hab sogar schon überlegt, das ganze ohne Affenformular und ohne redirects zu bauen, damit es noch leichter nachvollziehbar ist.

        […] - aber hier gehts um eine einfache Anleitung die entsprechende Grundlagen vermittelt und keine "do it perfectly"-Lösung.

        dafür

        Matthias

        --
        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Elf und Elfmetertöter.

      3. Hallo,

        In der Praxis würde ich das ganz anders aufbauen - aber hier gehts um eine einfache Anleitung die entsprechende Grundlagen vermittelt und keine "do it perfectly"-Lösung.

        Ich habe in https://forum.selfhtml.org/?t=215336&m=1474577 versucht zu argumentieren, warum das letztlich eine schlechte Idee ist. Warum fangen wir nicht mal damit an, Anfängern zu beschreiben, wie wir es in der Praxis machen würden.

        Natürlich muss man Vereinfachungen vornehmen, Nebenschauplätze ignorieren und den Code wiederverwendbar halten, klar. Aber vor allem aus didaktischen Gründen. Zum Beispiel finde ich PDO und Prepared Statements nicht komplexer als objektorientiertes mysqli mit sprintf-/real_escape_string-Orgien. Ich halte es letztlich sogar für einfacher, weil sich das Problem MySQL-Escaping damit in Luft auflöst. Man muss Low-Level-Operationen wie sprintf und real_escape_string nicht kennen und kann Escaping nicht vergessen.

        Diese Funktion ist kryptologisch zwar nicht ausreichend sicher, da der Salt-Wert aber ohnehin einen öffentlichen Teil des abgeleiteten Schlüssels darstellt, können wir diesen Umstand vernachlässigen. Zu seinem späteren Zeitpunkt kann die Funktion recht einfach durch password_hash() ersetzt werden, welche die auch die Erzeugung des Salt-Wertes selbst durchführen kann.

        Don’t make me think! Bei HTML, CSS und JavaScript predigen wir Progressive Enhancement, warum nicht auch bei PHP. Best Practice wäre, direkt password_hash und password_verify zu nutzen und ggf. password_compat einzubinden. Der kryptografische Hintergrund ist für den Anwender ohnehin unverständlich. Es reicht zu sagen: Dies ist der vorgesehene, sichere Weg und für ältere PHP-Versionen bauen wir die Funktion so gut es geht nach. Damit spart man sich obigen Krypto-Exkurs und kann sich auf die wichtigen Dinge beschränken, die beim Anwender hängen bleiben sollen. Die Nachricht sollte sein: Nutze gehashte, gesalzene Passwörter, mach es nicht selbst, sondern verwende Standard-PHP-Tools und vorgegebene sichere Algorithmen.

        Generell sollten wir Artikel für die Zukunft schreiben, die die heutigen Best Practices dokumentieren und eine gewisse Halbwertszeit haben. Fallbacks für alte PHP-Versionen kann man einbauen. Sie sind aber nur für die technische Funktionsfähigkeit nötig. Die darin verwendeten Techniken braucht der Anwender nicht zu verstehen geschweige denn sich zu merken.

        Grüße,
        Mathias

        1. Ich habe in https://forum.selfhtml.org/?t=215336&m=1474577 versucht zu argumentieren, warum das letztlich eine schlechte Idee ist. Warum fangen wir nicht mal damit an, Anfängern zu beschreiben, wie wir es in der Praxis machen würden.

          Das ist ein ganz anderer Ansatz als hier bisher verfolgt wird - die Idee gefällt mir ansich sehr gut, aber ist das didaktisch so sinnvoll, wenn man dem Leser einfach einen fertigen Brocke hinwirft den er ohne selbst zu denken kopieren kann - das widerspricht doch dem SELF gedanken.

          Zum Beispiel finde ich PDO und Prepared Statements nicht komplexer als objektorientiertes mysqli mit sprintf-/real_escape_string-Orgien.

          Da stimme ich dir zu.

          Man muss Low-Level-Operationen wie sprintf und real_escape_string nicht kennen und kann Escaping nicht vergessen.

          Wenn man drauf nicht vergessen kann, besteht aber die Gefahr, dass man sich garnicht mit der Thematik auseinandersetzen muss.

          Don’t make me think! Bei HTML, CSS und JavaScript predigen wir Progressive Enhancement, warum nicht auch bei PHP. Best Practice wäre, direkt password_hash und password_verify zu nutzen und ggf. password_compat einzubinden.

          Wie schon anderorts erwähnt habe ich mir das bereits überlegt - password_hash() und password_verify() sind allerdings nur in der PHP 5.5

          Der kryptografische Hintergrund ist für den Anwender ohnehin unverständlich. Es reicht zu sagen: Dies ist der vorgesehene, sichere Weg und für ältere PHP-Versionen bauen wir die Funktion so gut es geht nach.

          Es war mir hier wichtig dem Leser zu vermitteln, was in etwa zu tun ist um ein Passwort abzusichern - überall wird zwar davon gesprochen, aber der Weg - sprich was passiert und was diese unverständliche Zeichenkette tut bedarf Erklärung.

          Eben wie ich z.B. Grundlegend erkenne, wie meine Passwörter abgelegt sind. Auf den ersten Blick sehen ja alle mit crypt verarbeiteten Passwörter irgendwie gleich aus, aber MD5 mit crypt ist genauso unsicher wie MD5 ohne crypt, nur dass es durch das vorangestellte $1$ irgendwie fancy aussieht.

          Die Nachricht sollte sein: Nutze gehashte, gesalzene Passwörter, mach es nicht selbst, sondern verwende Standard-PHP-Tools und vorgegebene sichere Algorithmen.

          Wie oben erwähnt ist hier imho erforderlich, dass man zumindest grundlegend erklärt was gehasht/gesalzen usw. bedeutet.

          Generell sollten wir Artikel für die Zukunft schreiben, die die heutigen Best Practices dokumentieren und eine gewisse Halbwertszeit haben. Fallbacks für alte PHP-Versionen kann man einbauen. Sie sind aber nur für die technische Funktionsfähigkeit nötig.

          Da bin ich voll bei dir.

          Die darin verwendeten Techniken braucht der Anwender nicht zu verstehen geschweige denn sich zu merken.

          Spiesst sich das nicht mit dem Motto "Die Energie des Verstehens"? :)

          1. Hallo,

            Das ist ein ganz anderer Ansatz als hier bisher verfolgt wird - die Idee gefällt mir ansich sehr gut, aber ist das didaktisch so sinnvoll, wenn man dem Leser einfach einen fertigen Brocke hinwirft den er ohne selbst zu denken kopieren kann - das widerspricht doch dem SELF gedanken.

            Ich sehe keinen Sinn darin, absichtlich unvollständigen oder nicht funktionierenden Code zu veröffentlichen. Das macht niemanden schlauer oder regt zum Nachlesen an. Der Code sollte schon »fertig« und kopierbar/anpassbar sein.

            Die Form sollte ein Tutorial sein, d.h. es wird schrittweise erklärt, wie man zu der Lösung kommt. Davon gibt’s schon einige Artikel im Selfraum, z.B. das Fader-Framework.

            Man muss Low-Level-Operationen wie sprintf und real_escape_string nicht kennen und kann Escaping nicht vergessen.

            Wenn man drauf nicht vergessen kann, besteht aber die Gefahr, dass man sich garnicht mit der Thematik auseinandersetzen muss.

            Bestenfalls muss man sich mit der Thematik auch nicht auseinandersetzen! Sämtliche großen Web-Frameworks haben das Problem Kontextwechsel auf verschiedenen Ebenen gelöst – indem ich Schnittstellen, Sprachen und Formate verwende, die ihren Kontext kennen und Escaping automatisch vornehmen.

            Nun kann man zwei Ansätze verfolgen:

            1. Ich versuche Leute dazu zu bringen, diese Abstraktionen zu verwenden.
            2. Ich versuche Leute dazu zu bringen, die fiesen Details der verschiedenen Kontextwechsel zu lernen und durch verschiedene String-Operationen anzuwenden.

            Weg 2 ist für mich von didaktischer, weniger von praktischer Wichtigkeit. Natürlich sollte ich wissen, wie ich es »zu Fuß« machen kann. Natürlich muss ich die grundsätzliche Thematik verstehen. Natürlich sollte ich wissen, warum ich gewisse APIs verwende und andere meide.

            Doch sollte Produktivcode nicht bei jedem trivialen MySQL-Statement manuelles Escaping vornehmen müssen. Das ist für mich dunkle Steinzeit und solcher Code sollte nirgendwo mehr geschrieben werden, schon gar nicht von Programmieranfängern. Ein Artikel heute sollte den Weg aufzeigen, wie man schrittweise von einer manuellen Lösung zu einer robusten, zeitgemäßen Lösung kommt.

            Es war mir hier wichtig dem Leser zu vermitteln, was in etwa zu tun ist um ein Passwort abzusichern - überall wird zwar davon gesprochen, aber der Weg - sprich was passiert und was diese unverständliche Zeichenkette tut bedarf Erklärung.

            Das finde ich auch gut und wichtig. Wie sinnvolles Password-Hashing funktioniert und wie sich der generierte String zusammensetzt, sollte natürlich erklärt werden. Es ging mir lediglich darum, dass veraltete Wege nicht detailliert beschrieben werden müssen.

            Grüße,
            Mathias

            1. Hallo

              Es war mir hier wichtig dem Leser zu vermitteln, was in etwa zu tun ist um ein Passwort abzusichern - überall wird zwar davon gesprochen, aber der Weg - sprich was passiert und was diese unverständliche Zeichenkette tut bedarf Erklärung.

              Das finde ich auch gut und wichtig. Wie sinnvolles Password-Hashing funktioniert und wie sich der generierte String zusammensetzt, sollte natürlich erklärt werden. Es ging mir lediglich darum, dass veraltete Wege nicht detailliert beschrieben werden müssen.

              Ist es an dieser Stelle nicht sinnvoller, den ganzen Komplex zu teilen? Zum Thema Kontextwechsel gibt es bereits einen guten Artikel, der evtl. um heute gängige Automatismen ergänzt werden kann. Meiner Meinung nach sollte auch das Thema "Erstellung 'guter' Passwörter" einen eigenen Artikel zu den Grundlagen und den "modernen" Umsetzungen bekommen, der aus dem Artikel "Loginsysteme" für weitergehende Informationen verlinkt wird.

              So kann man in dem Artikel die heute gängige Praxis abbilden und dennoch, ohne den Artikel selbst zu überfrachten, auf das Grundlagenwissen hinweisen.

              Tschö, Auge

              --
              Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
              Terry Pratchett, "Wachen! Wachen!"
              ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
              Veranstaltungsdatenbank Vdb 0.3
              1. Om nah hoo pez nyeetz, Auge!

                Meiner Meinung nach sollte auch das Thema "Erstellung 'guter' Passwörter" einen eigenen Artikel zu den Grundlagen und den "modernen" Umsetzungen bekommen, der aus dem Artikel "Loginsysteme" für weitergehende Informationen verlinkt wird.

                Der Artikel ist da: http://wiki.selfhtml.org/wiki/Grundlagen/Sicherheit/sichere_Passwortwahl

                Könntest du die Verlinkung übernehmen?

                Matthias

                --
                Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Plan und Plantage.

                1. Hallo

                  Meiner Meinung nach sollte auch das Thema "Erstellung 'guter' Passwörter" einen eigenen Artikel zu den Grundlagen und den "modernen" Umsetzungen bekommen, der aus dem Artikel "Loginsysteme" für weitergehende Informationen verlinkt wird.

                  Der Artikel ist da: http://wiki.selfhtml.org/wiki/Grundlagen/Sicherheit/sichere_Passwortwahl

                  Ok, der Artikel beschreibt, wie man als Mensch ein Passwort wählen soll [1]. In der hiesigen Diskussion geht es aber um das Thema, wie das vom Menschen gewählte Passwort auf technischen Systemen gespeichert werden soll (Salt; Anzahl der Durchläufe durch den Hashalgorythmus; Algorythmen, die nach aktuellem Wissen sicher oder eben nicht mehr sicher oder gar per se ungeeignet sind). Sprich: Wie funktioniert die Speicherung und der Abgleich von Passwörtern auf Computersystemen?

                  Könntest du die Verlinkung übernehmen?

                  Öhhm, wo soll die Verlinkung hin? In suits Entwurf? Ich weiß nicht, ob ich darin "herumpfuschen" sollte. ;-)

                  [1] Christians Artikel erschien ja schon im Jahr 2002. Dort gibt es ja noch einige andere Perlen. Die sind zumindest teilweise (noch?) nicht in's Wiki überführt. Sollen die noch eingefügt werden und wenn ja, wie ist das mit der Bearbeitbarkeit im Wiki. Die Artikel sind ja in sich geschlossene Pamphlete eines Autors.

                  Tschö, Auge

                  --
                  Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                  Terry Pratchett, "Wachen! Wachen!"
                  ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                  Veranstaltungsdatenbank Vdb 0.3
                  1. Om nah hoo pez nyeetz, Auge!

                    Öhhm, wo soll die Verlinkung hin? In suits Entwurf? Ich weiß nicht, ob ich darin "herumpfuschen" sollte. ;-)

                    Ich hatte gedacht, du beziehst dich auch auf diesen Loginsystem Artikel.

                    [1] Christians Artikel erschien ja schon im Jahr 2002. Dort gibt es ja noch einige andere Perlen. Die sind zumindest teilweise (noch?) nicht in's Wiki überführt. Sollen die noch eingefügt werden und wenn ja, wie ist das mit der Bearbeitbarkeit im Wiki. Die Artikel sind ja in sich geschlossene Pamphlete eines Autors.

                    An welche Perlen denkst du denn? Wir würden dann die Autoren fragen, ob sie was dagegen haben. Im Wiki lässt sich ohne Anmeldung arbeiten.

                    Matthias

                    --
                    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Deck und Deckhengst.

                    1. Hallo

                      Öhhm, wo soll die Verlinkung hin? In suits Entwurf? Ich weiß nicht, ob ich darin "herumpfuschen" sollte. ;-)

                      Ich hatte gedacht, du beziehst dich auch auf diesen Loginsystem Artikel.

                      Ahh ja, nein, dessen Existenz war mir nicht bewusst. Nach einem Vergleich der ersten Absätze ist er wohl die Basis von suits' Entwurfs. Ich habe den Link zu Christian Kruses Artikel in die Weblinks eingefügt.

                      [1] Christians Artikel erschien ja schon im Jahr 2002. Dort gibt es ja noch einige andere Perlen. Die sind zumindest teilweise (noch?) nicht in's Wiki überführt. Sollen die noch eingefügt werden und wenn ja, wie ist das mit der Bearbeitbarkeit im Wiki. Die Artikel sind ja in sich geschlossene Pamphlete eines Autors.

                      An welche Perlen denkst du denn? Wir würden dann die Autoren fragen, ob sie was dagegen haben. Im Wiki lässt sich ohne Anmeldung arbeiten.

                      Ich habe mal die oben schon verlinkte chronologische Übersicht der Artikel nach meinen eigenen Interessen (!) durchstöbert. Die Aufzählung erhebt also keinen Anspruch auf Vollständigkeit. Für andere werden andere Artikel bewahrenswert sein.

                      Dabei ist mir aufgefallen, dass viele Artikel veraltete bzw. mittlerweile unnötige Techniken erläutern. Zudem wurden Artikel, wie z.B. die Join-Artikel, die ich immer wieder mal nutze, bereits ins Wiki überführt. Es sind also doch nicht mehr so viele Artikel übrig geblieben, die *mMn* bewahrt werden sollten. Andererseits gibt es bestimmt Gründe, einzelne Artikel wegfallen zu lassen, da bessere und modernere Lösungen an anderer Stelle (egal ob auf Selfhtml oder auch woanders im Web) vorhanden sind. Inhalt um des Inhalts willen ist mMn Mumpitz.

                      Zu den bewahrenswerten Artikeln gehören für mich (mit einer Überprüfung) zumindest die folgenden.

                      Folgende Artikel zum Thema Barrieren und Usability sind zwar technisch teilweise veraltet, ihre Inhalte sollte aber für einen (oder mehrere) Artikel auf aktuellem technischen Stand herangezogen werden. Die Themen als solche sind ja noch immer aktuell.

                      Tschö, Auge

                      --
                      Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                      Terry Pratchett, "Wachen! Wachen!"
                      ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                      Veranstaltungsdatenbank Vdb 0.3
                      1. Om nah hoo pez nyeetz, Auge!

                        Ahh ja, nein, dessen Existenz war mir nicht bewusst. Nach einem Vergleich der ersten Absätze ist er wohl die Basis von suits' Entwurfs. Ich habe den Link zu Christian Kruses Artikel in die Weblinks eingefügt.

                        genau

                        Zu den bewahrenswerten Artikeln gehören für mich (mit einer Überprüfung) zumindest die folgenden.

                        7 Anfragen raus geschickt, eine unroutable address (Helga Parslow - WWW-Design für Sehbehinderte)

                        Matthias

                        --
                        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Wind und Windows.

                        1. Hallo

                          Zu den bewahrenswerten Artikeln gehören für mich (mit einer Überprüfung) zumindest die folgenden.

                          7 Anfragen raus geschickt, eine unroutable address (Helga Parslow - WWW-Design für Sehbehinderte)

                          Die Domain zu der Emailadresse gibt es mittlerweile nur noch pro forma, da die Organisation inzwischen in einer anderen aufgegangen ist (Zitat: Dieser Webserver existiert (fast) nicht mehr.). Ob Frau Parslow nach über zehn Jahren noch dort tätig ist, ist hier die nächste Frage.

                          Tschö, Auge

                          --
                          Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                          Terry Pratchett, "Wachen! Wachen!"
                          ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                          Veranstaltungsdatenbank Vdb 0.3
                      2. Om nah hoo pez nyeetz, Auge!

                        Für diese beiden liegt bereits das ok des Autors vor. Falls du Lust hast, kannst du mit der Übertragung ins Wiki beginnen.

                        Matthias

                        --
                        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Balsa und Balsam.

                        1. Hallo

                          Ich habe diesen Artikel übertragen. Allerdings habe ich erstmal sowohl den Link im Abschnitt "Wie lässt sich Content Usability untersuchen?" des ursprünglichen Artikels als auch die weiterführenden Links wegelassen. Alle Links zur Firmenseite des Autors zeigen nicht mehr auf die ursprünglichen Ziele (bei zwei der Links wird z.B. die dortige "Kopie" des Artikels aufgerufen), der Link "Kritieren für Content-Usability" (auf fh-hamburg.de) ist offensichtlich nicht mehr erreichbar.

                          Tschö, Auge

                          --
                          Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                          Terry Pratchett, "Wachen! Wachen!"
                          ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                          Veranstaltungsdatenbank Vdb 0.3
                          1. Hallo

                            Ich habe diesen Artikel übertragen.

                            ... und ich sollte auch den Link nennen ...

                            Den Artikel habe ich im Abschnitt "Artikel/Allgemein" untergebracht. Der Link zum Artikel selbst: http://wiki.selfhtml.org/wiki/Artikel:Content_Usability

                            Tschö, Auge

                            --
                            Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                            Terry Pratchett, "Wachen! Wachen!"
                            ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                            Veranstaltungsdatenbank Vdb 0.3
                            1. Tach!

                              Den Artikel habe ich im Abschnitt "Artikel/Allgemein" untergebracht. Der Link zum Artikel selbst: http://wiki.selfhtml.org/wiki/Artikel:Content_Usability

                              Bitte neue Artikel nicht mehr im Namensraum Artikel (oder anderen) ablegen, nur in den Hauptnamensraum. Die Einteilung in diese Namensräume war von Anfang an ein Fehler (es hat nur noch niemand grundlegend aufgeräumt). Auch die Strukturierung muss diesbezüglich noch geändert werden. Für den Leser ist es nicht ersichtlich, ob eine Information in Artikelform oder sonstwie vorliegt, der sucht in der Struktur nach inhaltlichen Gesichtspunkten und sollte das nicht an x Stellen tun. Was früher mal "Artikel" war, gehört wie alles andere in die fachlichen Bereiche einsortiert.

                              dedlfix.

                              1. Hallo

                                Tach!

                                auch

                                Den Artikel habe ich im Abschnitt "Artikel/Allgemein" untergebracht. Der Link zum Artikel selbst: http://wiki.selfhtml.org/wiki/Artikel:Content_Usability

                                Bitte neue Artikel nicht mehr im Namensraum Artikel (oder anderen) ablegen, nur in den Hauptnamensraum. Die Einteilung in diese Namensräume war von Anfang an ein Fehler (es hat nur noch niemand grundlegend aufgeräumt). Auch die Strukturierung muss diesbezüglich noch geändert werden. Für den Leser ist es nicht ersichtlich, ob eine Information in Artikelform oder sonstwie vorliegt, der sucht in der Struktur nach inhaltlichen Gesichtspunkten und sollte das nicht an x Stellen tun. Was früher mal "Artikel" war, gehört wie alles andere in die fachlichen Bereiche einsortiert.

                                Ok, das ist plausibel. Ich hatte auch erst gesucht, wo ich den Artikel am passendsten einfügen kann und den Bereich Grundlagen/Praxisnah erwogen, da es dort schon die artverwandte Seite Benutzerfreundlichkeit und Barrierefreiheit gibt. Kann die Seite dorthin verschoben werden?

                                Tschö, Auge

                                --
                                Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
                                Terry Pratchett, "Wachen! Wachen!"
                                ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
                                Veranstaltungsdatenbank Vdb 0.3
                                1. Tach!

                                  Ich hatte auch erst gesucht, wo ich den Artikel am passendsten einfügen kann und den Bereich Grundlagen/Praxisnah erwogen, da es dort schon die artverwandte Seite Benutzerfreundlichkeit und Barrierefreiheit gibt. Kann die Seite dorthin verschoben werden?

                                  Habs verschoben (ohne Weiterleitung). Neue Adresse: http://wiki.selfhtml.org/wiki/Grundlagen/Praxisnah/Content_Usability

                                  dedlfix.

  3. Hi,

    zur Einführung ist vielleicht besser, erstmal die Grundlagen zu vermitteln, was ist eine Browser-Session und wie baut sich eine Solche auf. Hinweis: Session ist nicht $_SESSION, will gelegentlich meinen, dass die HTTP-Spezifikation keine Erfindung von PHP ist sondern aus dem vorigen Jahrtausend stammt (fossile RFCs).

    Den Krypt-Algorithmus sehe ich auch nicht als konstante Größe an, will meinen, es bleibt letztendlich dem Programmierer überlassen, was er da verwendet und zu verantworten hat er das selbst. Nichtsdestoweniger: Deine Ausführungen zu bcrypt sind OK und passen auch zum Thema. Wer das inhaltlich vertiefen will, kommt um ein eigenes Studium sowieso nicht herum und freut sich über die Links in Deinem Quellennachweis.

    Komplettlösung: Würde ich nicht in den Artikel nehmen, den würde ich allgemeiner aufbauen, so dass er einem Leser klarmacht, was hier zu tun ist (Abstraktion).

    Code zeigen: Klar, ja, als Beispiel, wie bestimmte Teilaufgaben gelöst werden können.

    Schönen Sonntag.

    1. Om nah hoo pez nyeetz, hotti!

      zur Einführung ist vielleicht besser, erstmal die Grundlagen zu vermitteln, was ist eine Browser-Session und wie baut sich eine Solche auf.

      Mach doch mal.

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Butt und Butter.

      1. hi,

        zur Einführung ist vielleicht besser, erstmal die Grundlagen zu vermitteln, was ist eine Browser-Session und wie baut sich eine Solche auf.

        Mach doch mal.

        Längst erledigt

        Viele Grüße!

        1. Om nah hoo pez nyeetz, hotti!

          Längst erledigt

          und für unser wiki?

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Pappe und Pappel.