tag:forum.selfhtml.org,2005:/self Reihenfolge beim Überprüfen neuer Passwörter – SELFHTML-Forum 2021-02-27T11:58:56Z https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784728#m1784728 vapita 2021-02-23T17:43:59Z 2021-02-23T17:43:59Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo liebe Gemeinde,</p> <p>angenommen, ich habe soeben per POST zwei Passwörter erhalten, die ich nun vergleichen und dann speichern möchte. Welche Reihenfolge ist am sinnvollsten? Oder ist es eigentlich egal?</p> <p>a)</p> <p>Ich prüfe, ob sie sich gleichen. Wenn ja -> hashen und speichern.</p> <p>b)</p> <p>Ich hashe beide Passwörter und prüfe, ob sie sich gleichen. Wenn ja -> speichern.</p> <p>c)</p> <p>Ich prüfe erstmal, ob es sich jeweils um einen String handelt. Wenn ja, vergleiche ich sie dann und hashe und speichere ggf.</p> <p>d)</p> <p>Ich prüfe, ob es Strings sind. Wenn ja, hashe und vergleiche ich sie und speichere dann ggf.</p> <p>Oder gibt es gar ein besseres Vorgehen?</p> <p>Beste Grüße und bleibt gesund</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784731#m1784731 Rolf B 2021-02-23T18:08:25Z 2021-02-23T18:19:51Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <p>du bekommst als POST oder GET Parameter immer nur Strings. Das musst Du also nicht wirklich prüfen. Prüfen könntest Du, ob die Parameter gefüllt oder leer waren (mit <code>empty($_POST['...'])</code>.</p> <p>Danach vergleichst Du. Das spart Zeit und Strom, denn wenn Du vor dem Vergleich hashen willst, musst Du zweimal hashen. Wenn Du zuerst vergleichst, nur einmal.</p> <p><s>Vom Ergebnis her ist es aber egal, denn die Arbeitshypothese beim Hashen ist ja, dass der Raum der möglichen Hashes so gigantisch ist, dass es keine unterschiedlichen User-Passworte gibt, die zum gleichen Hash führen. Und wenn doch, dann ist die Chance dafür astronomisch - äh - atomisch klein.</s></p> <p>Edit: Dieser Absatz würde nur gelten, wenn man nicht salzt. Aber <code>password_hash</code> streut Zufallssalz ein und liefert damit für gleiche Passwörter unterschiedliches Hashes. Thanks<a href="/users/26" class="mention registered-user" rel="noopener noreferrer">@tk</a>.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784732#m1784732 Robert B. 2021-02-23T18:12:48Z 2021-02-23T18:12:48Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin,</p> <blockquote> <p>angenommen, ich habe soeben per POST zwei Passwörter erhalten, die ich nun vergleichen und dann speichern möchte. Welche Reihenfolge ist am sinnvollsten? Oder ist es eigentlich egal?</p> <ol> <li>Ich prüfe, ob sie sich gleichen. Wenn ja -> hashen und speichern.</li> <li>Ich hashe beide Passwörter und prüfe, ob sie sich gleichen. Wenn ja -> speichern.</li> <li>Ich prüfe erstmal, ob es sich jeweils um einen String handelt. Wenn ja, vergleiche ich sie dann und hashe und speichere ggf.</li> <li>Ich prüfe, ob es Strings sind. Wenn ja, hashe und vergleiche ich sie und speichere dann ggf.</li> </ol> </blockquote> <p>Ich habe mal eine richtige Liste daraus gemacht.</p> <blockquote> <p>Oder gibt es gar ein besseres Vorgehen?</p> </blockquote> <p>Was ist denn deine Vermutung, welches Vorgehen am sinnvollsten ist?</p> <p>Die Optionen 3 und 4 brauchst du eigentlich nicht gesondert zu berücksichtigen, denn standardmäßig sind alle per POST übertragenen Werte erst einmal Strings. Du solltest allerdings die Passwörter nicht nur <em>Hashen</em>, sondern auch <em>Salzen</em>.</p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784733#m1784733 tk 2021-02-23T18:13:46Z 2021-02-23T18:13:46Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <blockquote> <p>angenommen, ich habe soeben per POST zwei Passwörter erhalten, die ich nun vergleichen und dann speichern möchte. Welche Reihenfolge ist am sinnvollsten? Oder ist es eigentlich egal?</p> </blockquote> <p>Nein, ist es nicht: <code>password_hash()</code> spuckt auch für den gleichen String nicht den gleichen Hash aus, du musst die Passwörter also erst vergleichen und dann hashen.</p> <p>Was du mit der Prüfung auf String genau meinst/bezweckst, weiß ich nicht - aber Daten die per POST (bzw. auch GET) reinkommen sind immer Strings, die Prüfung kannst du dir also sparen.</p> <blockquote> <p>Oder gibt es gar ein besseres Vorgehen?</p> </blockquote> <p>Vorgehen wofür? Vielleicht beschreibst du mal etwas genauer was du da wirklich vor hast bzw. was du da genau programmierst.</p> <p>Gruß,<br> Tobias</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784766#m1784766 localhorst 2021-02-24T09:04:16Z 2021-02-24T09:04:16Z Aufteilung der Funktion, MVC <p>Hallo vapita,<br> hallo Alle,</p> <p>hier ging es zunächst nur um die <strong>Reihenfolge</strong> der Arbeitsschritte. Inzwischen haben wir aber eine Menge weiterer Erkenntnisse gewonnen.</p> <p>Ich würde nun gerne noch lernen, wie man die Teilaufgaben richtig nach dem MVC-Modell verteilt. Es erscheint mir nicht sinnvoll, z.B. den Datenbankeintrag auch direkt in dieser Funktion vornehmen zu lassen, oder die HTML-Antwort komplett zu generieren, usw.</p> <p>Außerdem müsste man vor der Eintragung eines Passworthashes in die Tabelle wohl auch die Berechtigung dafür prüfen, also z.B. das alte Passwort abfragen und vergleichen, oder so. Und bei Neuanlage des Accounts würde man vielleicht noch einen Opt-In Roundturn benötigen, um Spammer zu verhindern.</p> <p>Ich würde mich deshalb freuen, wenn die Diskussion hier noch nicht abreißen würde.</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784804#m1784804 Raketenlagermeister 2021-02-24T14:53:40Z 2021-02-24T14:53:40Z Reihenfolge beim Überprüfen neuer Passwörter <p>Ich hab da was rumliegen, was das ein Formular für die Passworteingabe "baut" und die beiden Passwörter erst im Browser und dann auf dem Server checkt. Über die Qualität kann man sich streiten, es funktioniert aber:</p> <p>Ansehen:</p> <p><a href="https://home.fastix.org/Tests/PWForm/" rel="nofollow noopener noreferrer">https://home.fastix.org/Tests/PWForm/</a> (Die Dateien mit der Endung '.txt' kann man sich anschauen.)</p> <p>Testen:</p> <p><a href="https://home.fastix.org/Tests/PWForm/PWForm.php" rel="nofollow noopener noreferrer">https://home.fastix.org/Tests/PWForm/PWForm.php</a></p> <p>Das Hashen käme, wenn der Passwort-Check erfolgreich ist.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784735#m1784735 TS ts-self@online.de https://bitworks.de 2021-02-23T18:43:13Z 2021-02-23T19:44:23Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello,</p> <blockquote> <p>du bekommst als POST oder GET Parameter immer nur Strings. Das musst Du also nicht wirklich prüfen. Prüfen könntest Du, ob die Parameter gefüllt oder leer waren (mit <code>empty($_POST['...'])</code>.</p> </blockquote> <p>Nee, das ist zwar vermutlich hier trotzdem brauchbar, weil man keine Passworte akzeptieren will, die mur ein Digit haben, aber es ist formal falsch!</p> <p>Mit <a href="https://www.php.net/manual/en/function.empty" rel="nofollow noopener noreferrer">empty()</a> würden auch die Werte "0" und " " als <em>leer</em> identifiziert. Das will man sicherlich nicht.</p> <p>Die Prüfung müsste z. B. auf</p> <pre><code class="block language-php"> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password1'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token punctuation">(</span><span class="token function">strlen</span><span class="token punctuation">(</span><span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password1'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">### ...</span> <span class="token punctuation">}</span> </code></pre> <p>lauten.</p> <p>Reihenfolge:</p> <ol> <li>Vorhandensein der POST-Parameter mit isset() prüfen</li> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> <li>Mindestlänge prüfen</li> <li>verlangten Zeichenvorrat prüfen<br> 4a. auf erlaubte Zeichen prüfen<br> 4b. auf geforderte Anzahl von Versalien, Gemeinen, Ziffern, Sonderzeichen prüfen</li> <li>hashen (bitte nicht mehr mit md5(), sondern mit <a href="https://www.php.net/manual/en/function.password-hash.php" rel="nofollow noopener noreferrer">password_hash()</a> )</li> <li>eintragen</li> <li>ggf. Bestätigungsmail (selbstverständlich ohne das Passwort!) senden</li> </ol> <p>Und der ganze Vorgang <strong>muss</strong> über TLS laufen.</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784738#m1784738 vapita 2021-02-23T19:29:00Z 2021-02-23T19:29:00Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <p>ich hatte im Auge, dass password_hash einen String erwartet, daher die Idee.</p> <p>Stimmt, man kann sich einen hash sparen, wenn man vorher vergleicht.</p> <p>Danke für die Info.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784734#m1784734 Rolf B 2021-02-23T18:17:06Z 2021-02-23T18:17:06Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Robert,</p> <p>das macht <a href="https://www.php.net/manual/en/function.password-hash.php" rel="nofollow noopener noreferrer">password_hash</a> schon automatisch mit einem Zufallssalz. Ein eigenes, festes Salz zu verwenden, ist kontraproduktiv.</p> <p>Die Option, Salz mitzugeben, gibt es eh nur bei BCRYPT und ist seit PHP 7 missbilligt.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784743#m1784743 vapita 2021-02-23T20:32:03Z 2021-02-23T20:32:03Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Robert,</p> <p>danke erstmal. Ja, Option 3 und 4 sind vom Tisch. Ich habe die erste Variante benutzt, hatte aber auch überlegt, ob auch die anderen sinnvoll oder sinnvoller wären. Inzwischen kam jedoch heraus, dass man den Benutzer ja noch mit Mindestzeichenkettenlängen und Zeichenkomplexität ärgern kann. Also ist die Variante 1+ wohl die bisher sinnvollste.</p> <p>Zum einen möchte ich den Code möglichst übersichtlich gestalten, damit auch Außenstehende leicht nachvollziehen können, was ich da angestellt habe. Andererseits traue ich den Benutzereingaben nicht und möchte möglichst alle Fehlerquellen ausschließen.</p> <p>Daher prüfe ich zum Beispiel auch zusätzlich, ob es sich überhaupt um einen POST-Request handelt und ob ein gültiger CSRF-Token vom Formular mitgegeben wurde, ehe die Formular-Verarbeitung startet.</p> <blockquote> <p>Du solltest allerdings die Passwörter nicht nur Hashen, sondern auch Salzen.</p> </blockquote> <p>Daran hab ich auch noch nicht gedacht. Guter Hinweis.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784736#m1784736 vapita 2021-02-23T19:07:53Z 2021-02-23T19:17:37Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Tom,</p> <p>vielen Dank für den Input. Ich hatte es dann wohl nicht ganz richtig:</p> <pre><code class="block language-php"><span class="token variable">$password</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$passwordCheck</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password_check'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token operator">==</span> <span class="token variable">$passwordCheck</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordHashed</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">passwordEncoder</span><span class="token operator">-></span><span class="token function">hash</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$newUser</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$passwordHashed</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Die Passwörter stimmen nicht überein!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Habe es nun nach deiner Empfehlung so geändert:</p> <pre><code class="block language-php"><span class="token variable">$password</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$passwordCheck</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password_check'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token keyword">or</span> <span class="token operator">!</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$passwordCheck</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Es muss ein Passwort angegeben werden!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token operator">===</span> <span class="token variable">$passwordCheck</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordHashed</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">passwordEncoder</span><span class="token operator">-></span><span class="token function">hash</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$newUser</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$passwordHashed</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Die Passwörter stimmen nicht überein!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Punkt 3 und 4 müsste ich noch erledigen.</p> <p>Beste Grüße und vielen Dank</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784748#m1784748 dedlfix 2021-02-23T20:35:56Z 2021-02-23T20:35:56Z Reihenfolge beim Überprüfen neuer Passwörter <p>Tach!</p> <blockquote> <ol start="2"> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> </ol> </blockquote> <p>Warum typsicher? $_POST liefert Strings oder Arrays. Strings mit Arrays zu vergleichen liefert false. Gleiche Arrays liefern true, egal ob typsicher oder nicht. Der typsichere Vergleich ergibt keinen Unterschied zum nicht typsicheren und der unerlaubte Fall Array wird nicht bemerkt. Es ist hier also egal, ob typsicher verglichen wird oder nicht.</p> <blockquote> <p>4a. auf erlaubte Zeichen prüfen</p> </blockquote> <p>Welche Zeichen sollten verboten werden? Oder auch andersrum gefragt, welche sollen erlaubt sein? Warum soll das eingeschränkt sein?</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784800#m1784800 klawischnigg 2021-02-24T13:53:23Z 2021-02-24T13:53:23Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hi there,</p> <blockquote> <p>Reihenfolge:</p> <ol> <li>Vorhandensein der POST-Parameter mit isset() prüfen</li> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> <li>Mindestlänge prüfen</li> <li>verlangten Zeichenvorrat prüfen<br> 4a. auf erlaubte Zeichen prüfen<br> 4b. auf geforderte Anzahl von Versalien, Gemeinen, Ziffern, Sonderzeichen prüfen</li> <li>hashen (bitte nicht mehr mit md5(), sondern mit <a href="https://www.php.net/manual/en/function.password-hash.php" rel="nofollow noopener noreferrer">password_hash()</a> )</li> <li>eintragen</li> <li>ggf. Bestätigungsmail (selbstverständlich ohne das Passwort!) senden</li> </ol> </blockquote> <p>Eines hast Du noch vergessen:</p> <p>Im RAM mit dem Mikroskop nachschauen, wie die beiden Passwörter auf Bit-Ebene ausschauen...</p> <p>(scnr)</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784737#m1784737 TS ts-self@online.de https://bitworks.de 2021-02-23T19:19:59Z 2021-02-23T19:19:59Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello vapita,</p> <blockquote> <p>vielen Dank für den Input. Ich hatte es dann wohl nicht ganz richtig:</p> <pre><code class="block"> $password = $userData['password']; $passwordCheck = $userData['password_check']; </code></pre> </blockquote> <blockquote> <pre><code class="block"></code></pre> </blockquote> <p>Warum arbeitest Du nicht direkt mit den $_POST-Parametern?<br> Das mehrmalige Umkopieren von Parametern ist kontraproduktiv.</p> <pre><code class="block language-html"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password[a]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password[b]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> </code></pre> <pre><code class="block language-php"> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'a'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'b'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># ...</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token comment"># Fehlermeldung</span> </code></pre> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784741#m1784741 Rolf B 2021-02-23T19:59:07Z 2021-02-23T19:59:07Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <p>einerseits kannst Du direkt mit <code>$_GET</code> oder <code>$_POST</code> arbeiten, wie Tom vorschlug, aber <strong>wenn</strong> es für Dich Gründe gibt, dieses <code>$userData</code> Array zu verwenden (z.B. weil es ein Parameter für deine Methode ist), dann solltest Du die <code>isset</code>-Abfrage an der Stelle machen, wo Du die <code>$_POST</code>-Daten nach $userData überträgst.</p> <p>Denn andernfalls kommt die blöde Notice, dass Du auf einen undefinierten Key zugreifst, beim Übertragen nach $userData.</p> <p>Aber da hab ich grad was gelernt: Ab PHP 7 gibt es den <a href="https://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.coalesce" rel="nofollow noopener noreferrer">"null coalescing operator"</a> <code>??</code>. Der beinhaltet eine isset Abfrage!</p> <p><code>$_POST['password'] ?? ""</code> liefert den geposteten Wert des Passworts, und wenn die POST-Daten keinen Eintrag für password enthalten, sorgt ?? zum einen dafür, dass die Notice nicht kommt, und zum anderen setzt er "" als Ersatzwert.</p> <p>Also, wenn Du PHP 7 aufwärts verwendest, kannst Du es so machen:</p> <pre><code class="block language-php"><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span> <span class="token operator">??</span> <span class="token string double-quoted-string">""</span><span class="token punctuation">;</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password_check'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$_POST</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password_check'</span><span class="token punctuation">]</span> <span class="token operator">??</span> <span class="token string double-quoted-string">""</span><span class="token punctuation">;</span> </code></pre> <p>und hast für fehlende Passworte einen Leerstring in $userData stehen.</p> <p>Beim Hashen würde ich dann als erstes die Gleichheit testen, und zwar ohne mir die Mühe zu machen, das check-Passwort in eine Variable zu laden. Danach muss die erforderliche Passwordkomplexität geprüft werden (lang genug, Zeichenmix), und DANN kann man hashen. Hier wäre meine Frage, was dein passwordEncoder Objekt tut. Ist das was selbstgemachtes? Oder nur eine Hülle um die eingebaute password_hash Funktion von PHP? Wenn es nicht password_hash ist: Wegschmeißen. In PHP selbstgebautes Hashing ist entweder zu trivial oder zu langsam, und die älteren Passwortfunktionen sind unsicher. Wenn Du crypt() verwendest, ok, das tut password_hash auch, aber letztere sorgt für starkes Salz und bietet mit password_verify und password_needs_rehash sinnvolle Tools dazu. Falls Du md5() verwendest: Nein. Zu unsicher.</p> <pre><code class="block language-php"><span class="token variable">$password</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token operator">!==</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'passwordCheck'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Die Passwörter stimmen nicht überein!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">verifyPasswordComplexity</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Das Password ist nicht stark genug!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$passwordHashed</span> <span class="token operator">=</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reicht!</span> <span class="token variable">$newUser</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$passwordHashed</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>(Wieso eigentlich break? Läuft das in einer Schleife?! Benutzt Du eine Schleifenkonstruktion, um einen GOTO zu simulieren?)</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784740#m1784740 vapita 2021-02-23T19:58:54Z 2021-02-23T19:58:54Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <p>Warum arbeitest Du nicht direkt mit den $_POST-Parametern?<br> Das mehrmalige Umkopieren von Parametern ist kontraproduktiv.</p> <pre><code class="block language-html"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password[a]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>password[b]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> </code></pre> </blockquote> <p>Ich hole mir die Daten über eine Request-Klasse, die mir die Eingaben gleich filtert:</p> <pre><code class="block language-php"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">getQuery</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$FormFieldName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$FormFieldName</span> <span class="token operator">!==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token function">filter_input</span><span class="token punctuation">(</span><span class="token constant">INPUT_POST</span><span class="token punctuation">,</span> <span class="token variable">$FormFieldName</span><span class="token punctuation">,</span> <span class="token constant">FILTER_SANITIZE_STRIPPED</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">query</span> <span class="token operator">=</span> <span class="token variable">$query</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">newMessage</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">customErrorMsg</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Im Controller speichere ich dann die Daten in einer Variablen, bzw. im Array $userData, da ich dieses später noch in der View benötige, um die Benutzereingaben nach einer Fehlermeldung als Formwerte zu erhalten.</p> <pre><code class="block language-php"><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'firstname'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'firstname'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'lastname'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'lastname'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>Ich habe den Code nochmals angepasst und folgendes ist dabei herausgekommen:</p> <pre><code class="block language-php"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'a'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'b'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'a'</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'b'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordHashed</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">passwordEncoder</span><span class="token operator">-></span><span class="token function">hash</span><span class="token punctuation">(</span><span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'a'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$newUser</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$passwordHashed</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Die Passwörter stimmen nicht überein!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Es muss ein Passwort angegeben werden!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784739#m1784739 TS ts-self@online.de https://bitworks.de 2021-02-23T19:36:56Z 2021-02-23T19:36:56Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello vapita,</p> <blockquote> <p>ich hatte im Auge, dass password_hash einen String erwartet, daher die Idee.</p> <p>Stimmt, man kann sich einen hash sparen, wenn man vorher vergleicht.</p> </blockquote> <p>Man darf nur einmal hashen, wenn man <a href="https://www.php.net/manual/en/function.password-hash" rel="nofollow noopener noreferrer">password_hash()</a> und später zum Vergleichen <a href="https://www.php.net/manual/en/function.password-verify.php" rel="nofollow noopener noreferrer">password_verify()</a> benutzen will.</p> <p>Die Funktion <code>password_hash()</code> produziert nämlich bei jedem Aufruf einen neuen Passwortschlüssel. Dieser enthält dann alle Daten (mit Ausnahme des Passwortes im Klartext), die <code>password_verify()</code> später zum Vergleichen benötigt.</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784742#m1784742 vapita 2021-02-23T20:12:32Z 2021-02-23T20:12:32Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <blockquote> <p>Denn andernfalls kommt die blöde Notice, dass Du auf einen undefinierten Key zugreifst, beim Übertragen nach $userData.</p> </blockquote> <p>Das ist ein guter Hinweis. Ist mir tatsächlich schon passiert. Dann werde ich das nochmals anpassen.</p> <blockquote> <p>Hier wäre meine Frage, was dein passwordEncoder Objekt tut. Ist das was selbstgemachtes? Oder nur eine Hülle um die eingebaute password_hash Funktion von PHP?</p> </blockquote> <p>Genau, es ist nur eine Hülle. Als Algo benutze ich PASSWORD_DEFAULT.</p> <pre><code class="block language-php"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Password</span> <span class="token punctuation">{</span> <span class="token comment">/** * @param $plain_password * @return false|string|null */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token constant">PASSWORD_DEFAULT</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $plain_password * @param $correct_hash * @return bool */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">validate</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_verify</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <pre><code class="block language-php"><span class="token variable">$password</span> <span class="token operator">=</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token operator">!==</span> <span class="token variable">$userData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'passwordCheck'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Die Passwörter stimmen nicht überein!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">verifyPasswordComplexity</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Das Password ist nicht stark genug!'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$passwordHashed</span> <span class="token operator">=</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reicht!</span> <span class="token variable">$newUser</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$passwordHashed</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> </blockquote> <p>Danke, danke, so werde ich es umsetzen.</p> <blockquote> <p>(Wieso eigentlich break? Läuft das in einer Schleife?! Benutzt Du eine Schleifenkonstruktion, um einen GOTO zu simulieren?)</p> </blockquote> <p>Ja, ich wollte tiefe IF-Schleifen-Schachteln vermeiden und nutze dafür:</p> <pre><code class="block language-php"><span class="token keyword">do</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$error</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token constant boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784744#m1784744 Rolf B 2021-02-23T20:32:23Z 2021-02-23T20:32:23Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <blockquote> <p>IF-Schleifen</p> </blockquote> <p>Brrrrrr</p> <p>Wenn Methoden zu komplex werden, teilt man sie auf. Ab PHP 7 ist ein Funktions-/Methodenaufruf nicht mehr so teuer. Die Idee ist, dass eine Methode sich um genau eine Aufgabe kümmert. Wird sie länger als 50 Zeilen, läuft zumeist was falsch.</p> <p>Wenn Du eine Methode hast, die drölf Prüfungen macht und nach jeder Prüfung mit BREAK aussteigen kann, dann solltest Du jede dieser Prüfungen in eine eigene, private Methode auslagern, und sie einfach nacheinander aufrufen.</p> <pre><code class="block language-php"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">do_a_lot</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$success</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">do_thing_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">do_thing_2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">...</span> <span class="token operator">&&</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">do_thing_13</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$success</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Log Error - falls noch nötig</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Die Einzelmethoden müssen nur mit return false; aussteigen, um den Ablauf abzubrechen. PHP verwendet wie einige andere Sprachen auch die sogenannte Kurzschluss-Logik: Wenn bei <code>A && B</code> oder <code>A || B</code> nach der Auswertung von A schon feststeht, wie das Ergebnis ist, wird B nicht mehr angefasst. Bei && ist es klar, wenn A zu FALSE wird, und bei || ist es klar, wenn A zu TRUE wird.</p> <p>In <code>$this->doThis() && $this->doThat()</code> wird <code>doThat</code> nur aufgerufen, wenn <code>doThis</code> TRUE zurückgibt (oder etwas, das der Type Juggler zu TRUE macht).</p> <p>Es kommt auch vor, dass man in den einzelnen Schritten Teilergebnisse bestimmt, die in den folgenden Schritten gebraucht werden. Sie dann als Parameter zur übergeben, ist unhandlich. Sowas deutet aber darauf hin, dass diese Methode lieber ein eigenes Objekt sein möchte, ein Worker. Statt die Monstermethode aufzurufen, instanziierst Du den Worker, rufst seine offizielle Methode auf (z.B. "Run" oder "Validate" oder was grad passt) und der macht dann intern rum. Die privaten Methoden, die drinstecken, verwenden private Properties, um sich Daten zuzuspielen. Das ist absolut okay.</p> <p>Der Vorteil ist auch, dass man einen solchen Worker wiederverwenden und isoliert testen kann.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784746#m1784746 TS ts-self@online.de https://bitworks.de 2021-02-23T20:35:04Z 2021-02-23T21:05:36Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello vapita,</p> <blockquote> <p>Ja, ich wollte tiefe IF-Schleifen-Schachteln vermeiden und nutze dafür:</p> </blockquote> <p>Ach, die berühmten <a href="http://if-schleife.de/" rel="nofollow noopener noreferrer">IF-SCHLEIFEN</a> ;-)</p> <p><a href="http://blog.ebene7.com/2010/01/15/und-es-gibt-sie-doch-if-schleifen-so-wird-es-nicht-gemacht/" rel="nofollow noopener noreferrer">Oder gibt es sie doch?</a></p> <blockquote> <pre><code class="block language-php"><span class="token keyword">do</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$error</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token constant boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> </blockquote> <p>Das Ganze kannst Du auch als leicht lesbare Funktion aufbauen.</p> <pre><code class="block language-php"><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token function">insert_new_pass</span><span class="token punctuation">(</span><span class="token variable">$pass1</span><span class="token punctuation">,</span> <span class="token variable">$pass2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Eine Passwortangabe fehlt'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Passworte stimmen nicht überein'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test3</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Passwortlänge zu kurz'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test4</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Unerlaubte Zeichen im Passwort'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test5</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Es muss mindestens ein Groß, ein Klein, eine Ziffer, ein Sonderzeichen im Passwort enthalten sein'</span><span class="token punctuation">;</span> <span class="token comment"># ...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">db_insert_password</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Eintragung in die DB nicht möglich'</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Prüfen musst Du dann nach dem Aufruf der Funktion auf</p> <p><code>if (($message = insert_new_pass()) === true</code> ## weitermachen, sonst $message ausgeben.</p> <p>Und anstelle der statischen Fehlermeldungen und <strong>TRUE</strong> könntest Du auch Fehlernummern und <strong>0</strong> zurückgeben. Dann kannst Du die Fehlermeldungen anhand der Nummer sprachabhängig ausgeben lassen.</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784745#m1784745 Rolf B 2021-02-23T20:33:07Z 2021-02-23T20:33:07Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <blockquote> <p>Daran hab ich auch noch nicht gedacht.</p> </blockquote> <p>Doch, hast Du. password_hash salzt automatisch, es sei denn, du streust das Salz von Hand. Was aber nicht mehr erwünscht ist.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784761#m1784761 Robert B. 2021-02-24T07:55:58Z 2021-02-24T07:55:58Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin vapita,</p> <blockquote> <p>danke erstmal. Ja, Option 3 und 4 sind vom Tisch. Ich habe die erste Variante benutzt, hatte aber auch überlegt, ob auch die anderen sinnvoll oder sinnvoller wären.</p> </blockquote> <p>Option 2 hat den Nachteil, dass du unnötig Rechenzeit verschwendest. Und im Fall von <code>password_hash</code> wird es auch nicht zum Erfolg führen, da der Salt zweiter Aufrufe hintereinander unterschiedlich ist.</p> <blockquote> <p>Inzwischen kam jedoch heraus, dass man den Benutzer ja noch mit Mindestzeichenkettenlängen und Zeichenkomplexität ärgern kann. Also ist die Variante 1+ wohl die bisher sinnvollste.</p> </blockquote> <p>Passwörter sollten für den Nutzer kein Ärgernis, sondern gut zu merken sein. Ich empfehle da immer den <a href="https://xkcd.com/936/" rel="nofollow noopener noreferrer">xkcd-Comic zur Passwortkomplexität</a>.</p> <blockquote> <p>Zum einen möchte ich den Code möglichst übersichtlich gestalten, damit auch Außenstehende leicht nachvollziehen können, was ich da angestellt habe. Andererseits traue ich den Benutzereingaben nicht und möchte möglichst alle Fehlerquellen ausschließen.</p> </blockquote> <p>Was sind denn „Fehlerquellen“ in Bezug auf Passwörter?</p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784747#m1784747 vapita 2021-02-23T20:35:46Z 2021-02-23T20:35:46Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <blockquote> <p>Doch, hast Du. password_hash salzt automatisch, es sei denn, du streust das Salz von Hand. Was aber nicht mehr erwünscht ist.</p> </blockquote> <p>Ich sollte vielleicht doch einmal einen genaueren Blick auf die PHP-Docs werfen. Danke auch für diesen Hinweis.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784770#m1784770 vapita 2021-02-24T10:17:09Z 2021-02-24T10:17:09Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Tom,</p> <blockquote> <p>Ach, die berühmten <a href="http://if-schleife.de/" rel="nofollow noopener noreferrer">IF-SCHLEIFEN</a> ;-)</p> <p><a href="http://blog.ebene7.com/2010/01/15/und-es-gibt-sie-doch-if-schleifen-so-wird-es-nicht-gemacht/" rel="nofollow noopener noreferrer">Oder gibt es sie doch?</a></p> </blockquote> <p>Da hatte ich wohl einen Knoten im Gehirn. Es ist natürlich eine IF-Abfrage, keine -Schleife. Jedenfalls nicht in meinem Fall. Danke für den Hinweis auf die nette Lektüre. </p> <blockquote> <p>Das Ganze kannst Du auch als leicht lesbare Funktion aufbauen.</p> <pre><code class="block language-php"><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token function">insert_new_pass</span><span class="token punctuation">(</span><span class="token variable">$pass1</span><span class="token punctuation">,</span> <span class="token variable">$pass2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Eine Passwortangabe fehlt'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Passworte stimmen nicht überein'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test3</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Passwortlänge zu kurz'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test4</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Unerlaubte Zeichen im Passwort'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">test5</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Es muss mindestens ein Groß, ein Klein, eine Ziffer, ein Sonderzeichen im Passwort enthalten sein'</span><span class="token punctuation">;</span> <span class="token comment"># ...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token function">db_insert_password</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'Fehler: Eintragung in die DB nicht möglich'</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Prüfen musst Du dann nach dem Aufruf der Funktion auf</p> <p><code>if (($message = insert_new_pass()) === true</code> ## weitermachen, sonst $message ausgeben.</p> <p>Und anstelle der statischen Fehlermeldungen und <strong>TRUE</strong> könntest Du auch Fehlernummern und <strong>0</strong> zurückgeben. Dann kannst Du die Fehlermeldungen anhand der Nummer sprachabhängig ausgeben lassen.</p> </blockquote> <p>Ich habe die Anregungen umgesetzt und die Password-Klasse etwas umgearbeitet:</p> <pre><code class="block language-php"> <span class="token comment">/** * @param $plain_password * @return false|string|null */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$plain_password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$plain_password</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token constant">PASSWORD_DEFAULT</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <pre><code class="block language-php"> <span class="token comment">/** * @param string $plain_password * @param string $correct_hash * @return bool */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">verify</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token keyword type-hint">string</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_verify</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <pre><code class="block language-php"> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isString</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$passwordIsString</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Ich prüfe, ob das Passwort (oder die Passwörter, wenn es ein Array ist) ein String ist.</p> <pre><code class="block language-php"> <span class="token comment">/** * @param array $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isEqual</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <pre><code class="block language-php"> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">hasMinLength</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">strlen</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Ich prüfe einmal mit strlen() die Zeichenlänge, jedoch brauch ich das gar nicht mehr, da ich bereits mit isComplex() prüfe, ob das Passwort lang genug ist, oder?</p> <pre><code class="block language-php"> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isAllowed</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// TODO: auf erlaubte Zeichen prüfen</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Ich bin mir noch nicht sicher, wie ich prüfe, ob nicht erlaubte Zeichen enthalten sind, bzw. welche das eigentlich sein sollen. Ich würde es wahrscheinlich auf lateinische Buchstaben, arabische Ziffern und die Sonderzeichen @#-_$%^&+=§!? begrenzen.</p> <pre><code class="block language-php"> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token comment">/** Das Passwort muss mindestens * - einen Kleinbuchstaben, * - einen Großbuchstaben, * - eine Ziffer und * - ein Sonderzeichen @#-_$%^&+=§!? * enthalten. * Das Passwort muss zwischen 8 und 20 Zeichen lang sein. */</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">preg_match</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/^(?=.*\d)(?=.*[@#\-_$%^&+=§!\?])(?=.*[a-z])(?=.*[A-Z])[0-9A-Za-z@#\-_$%^&+=§!\?]{8,20}$/'</span><span class="token punctuation">,</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">?</span> <span class="token constant boolean">true</span> <span class="token punctuation">:</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Hier prüfe ich ja eigentlich auch nochmals die Zeichenkettenlänge. Entferne ich dies hier wieder oder lasse ich einfach die hasMinLentgh() weg?</p> <pre><code class="block language-php"> <span class="token comment">/** * @param array $password * @return int */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">validate</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token keyword return-type">int</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isString</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1601</span><span class="token punctuation">;</span> <span class="token comment">// kein String</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isEqual</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1602</span><span class="token punctuation">;</span> <span class="token comment">// stimmt nicht überein</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">hasMinLength</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1603</span><span class="token punctuation">;</span> <span class="token comment">// ist nicht lang genug</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isAllowed</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1604</span><span class="token punctuation">;</span> <span class="token comment">// verwendet nicht erlaubte Zeichen</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1605</span><span class="token punctuation">;</span> <span class="token comment">// ist nicht komplex genug</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// alles in Ordnung</span> <span class="token punctuation">}</span> </code></pre> <p>So ist es tatsächlich übersichtlicher. Da hab ich wieder was gelernt. Vielen Dank dafür.</p> <p>Die Idee mit den Fehlercodes gefällt mir gut. In der View rufe ich die Fehlermeldung dann über ein Array ab.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784759#m1784759 Robert B. 2021-02-24T07:45:24Z 2021-02-24T07:45:24Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin vapita,</p> <blockquote> <p>Ich sollte vielleicht doch einmal einen genaueren Blick auf die PHP-Docs werfen.</p> </blockquote> <p><em>Das</em> sollte man auf jeden Fall immer tun.</p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784749#m1784749 TS ts-self@online.de https://bitworks.de 2021-02-23T20:46:47Z 2021-02-23T20:46:47Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello,</p> <blockquote> <blockquote> <ol start="2"> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> </ol> </blockquote> <p>Warum typsicher? $_POST liefert Strings oder Arrays. Strings mit Arrays zu vergleichen liefert false. Gleiche Arrays liefern true, egal ob typsicher oder nicht. Der typsichere Vergleich ergibt keinen Unterschied zum nicht typsicheren und der unerlaubte Fall Array wird nicht bemerkt. Es ist hier also egal, ob typsicher verglichen wird oder nicht.</p> </blockquote> <p>Ok, sehe ich ein.</p> <p>Man müsste also die beiden $_POST-Parameter auf <a href="https://www.php.net/manual/en/function.is-string" rel="nofollow noopener noreferrer">is_string()</a> prüfen, damit nicht nachher der Hash von "array" gebildet wird.</p> <blockquote> <blockquote> <p>4a. auf erlaubte Zeichen prüfen</p> </blockquote> <p>Welche Zeichen sollten verboten werden? Oder auch andersrum gefragt, welche sollen erlaubt sein? Warum soll das eingeschränkt sein?</p> </blockquote> <p>Das kann ich nicht beantworten. Hängt sicherlich von Umfeld und Reichweite der Anwendung ab.</p> <p>Sinnvoll könnte die Einschränkung auf international zugängliche Zeichen sein, damit ich mich auch auf einem chinedsischen Computer an meinem Account anmelden kann ;-P</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784776#m1784776 localhorst 2021-02-24T11:34:20Z 2021-02-24T11:34:20Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo dedlfix,<br> hallo Alle,</p> <blockquote> <blockquote> <ol start="2"> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> </ol> </blockquote> <p>Warum typsicher? $_POST liefert Strings oder Arrays. Strings mit Arrays zu vergleichen liefert false. Gleiche Arrays liefern true, egal ob typsicher oder nicht. Der typsichere Vergleich ergibt keinen Unterschied zum nicht typsicheren und der unerlaubte Fall Array wird nicht bemerkt. Es ist hier also egal, ob typsicher verglichen wird oder nicht.</p> </blockquote> <p>Was kommt raus, wenn man</p> <p><code>var_dump("□□□□□□□□"=="00000000");</code><br> oder<br> <code>var_dump("□□□□□□□□"==="00000000");</code><br> oder auch<br> linke und rechte Seite vertauscht.</p> <p>ausführt? Die Kästchen sollen Leerzeichen sein.</p> <p>Ich habe leider kein php zur Verfügung im Moment.</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784750#m1784750 localhorst 2021-02-23T20:56:58Z 2021-02-23T20:56:58Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo TS,<br> hallo Alle,</p> <blockquote> <p>Man müsste also die beiden $_POST-Parameter auf <a href="https://www.php.net/manual/en/function.is-string" rel="nofollow noopener noreferrer">is_string()</a> prüfen, damit nicht nachher der Hash von "array" gebildet wird.</p> </blockquote> <p>Oh, wieder was gelernt. Das wäre ja wirklich nicht schön.</p> <blockquote> <blockquote> <blockquote> <p>4a. auf erlaubte Zeichen prüfen</p> </blockquote> <p>Welche Zeichen sollten verboten werden? Oder auch andersrum gefragt, welche sollen erlaubt sein? Warum soll das eingeschränkt sein?</p> </blockquote> <p>Das kann ich nicht beantworten. Hängt sicherlich von Umfeld und Reichweite der Anwendung ab.</p> <p>Sinnvoll könnte die Einschränkung auf international zugängliche Zeichen sein, damit ich mich auch auf einem chinedsischen Computer an meinem Account anmelden kann ;-P</p> </blockquote> <p>Vielleicht willst Du das Passwort ja auf deinem alten Fernschreiber drucken?</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784751#m1784751 dedlfix 2021-02-23T21:01:19Z 2021-02-23T21:01:19Z Reihenfolge beim Überprüfen neuer Passwörter <p>Tach!</p> <blockquote> <p>Man müsste also die beiden $_POST-Parameter auf <a href="https://www.php.net/manual/en/function.is-string" rel="nofollow noopener noreferrer">is_string()</a> prüfen, damit nicht nachher der Hash von "array" gebildet wird.</p> </blockquote> <p>Da du ja die Komplexität prüfen möchtest, würde das eigentlich da schon durchfallen. Aber selbst wenn das Array es bis zum password_hash() schafft, würde die Unternehmung dort zu Ende sein, denn dann gibt es einen fatalen Fehler wegen falschen Typs.</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784753#m1784753 Rolf B 2021-02-23T22:09:16Z 2021-02-23T22:09:16Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo TS,</p> <blockquote> <p>damit nicht nachher der Hash von "array" gebildet wird.</p> </blockquote> <p>Das ist tatsächlich eine üble Sache.</p> <p>Im Normalfall wird das nicht vorkommen, solange das Form korrekt aufgebaut ist. Aber wehe, ein Script-Kiddie postet irgendwelchen vorsätzlichen Müll.</p> <p>Ich habe das gerade mal ausprobiert. Laut Doku liefert password_hash ja FALSE, wenn ein Fehler auftritt. Wenn man ein Array als ersten Parameter hineingibt, wirft PHP eine Warnung, dass da ein Array statt eines Strings kam.</p> <p>Und die Rückgabe ist: NULL. Nicht FALSE. Auch, wenn man Müll als Passwortalgorithmus übergibt, ist die Rückgabe NULL. Nicht false. Kommt mir wie ein böser Bug vor.</p> <p>Man muss die Rückgabe von password_hash also auf NULL und FALSE prüfen, um festzustellen, dass da was schief ging.</p> <p>Und die Prüfung der Eingabe auf is_array ist sicherlich auch sinnvoll. Da hilft aber tatsächlich filter_input - das liefert FALSE wenn im Parameter ein Array steht. Und NULL wenn der Parameter nicht existiert, ein paar ifs wird man also bauen müssen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784752#m1784752 kai345 2021-02-23T21:28:16Z 2021-02-23T21:28:16Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <blockquote> <p>Sinnvoll könnte die Einschränkung auf international zugängliche Zeichen sein, damit ich mich auch auf einem chinedsischen Computer an meinem Account anmelden kann ;-P</p> </blockquote> <p>Vielleicht willst Du das Passwort ja auf deinem alten Fernschreiber drucken?</p> </blockquote> <p><a href="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png?size=medium" alt="ITA2" title="Lochstreifen ITA2" loading="lazy"></a></p> <div class="signature">-- <br> Stur lächeln und winken, Männer! </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784767#m1784767 localhorst 2021-02-24T09:11:00Z 2021-02-24T09:15:26Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo dedlfix,<br> hallo Alle,</p> <blockquote> <blockquote> <p>Man müsste also die beiden $_POST-Parameter auf <a href="https://www.php.net/manual/en/function.is-string" rel="nofollow noopener noreferrer">is_string()</a> prüfen, damit nicht nachher der Hash von "array" gebildet wird.</p> </blockquote> <p>Da du ja die Komplexität prüfen möchtest,</p> </blockquote> <p>Was bedeutet <strong>hier</strong> "Komplexität prüfen"?<br> Ich hab da zwar <a href="https://de.m.wikipedia.org/wiki/Komplexit%C3%A4t_(Informatik)" rel="nofollow noopener noreferrer">was gefunden</a>, werde aber nicht richtig schlauer daraus.</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784788#m1784788 TS ts-self@online.de https://bitworks.de 2021-02-24T12:31:19Z 2021-02-24T12:32:07Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello,</p> <blockquote> <blockquote> <blockquote> <p>Sinnvoll könnte die Einschränkung auf international zugängliche Zeichen sein, damit ich mich auch auf einem chinedsischen Computer an meinem Account anmelden kann ;-P</p> </blockquote> <p>Vielleicht willst Du das Passwort ja auf deinem alten Fernschreiber drucken?</p> </blockquote> <p><a href="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png?size=medium" alt="ITA2" title="Lochstreifen ITA2" loading="lazy"></a></p> </blockquote> <p>Als Lochmuster hättest Du nun noch ein visuelles (also nicht codiertes) "selfHTML it toll" stanzen können ;-)</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784796#m1784796 Robert B. 2021-02-24T13:17:59Z 2021-02-24T13:17:59Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin Kai,</p> <blockquote> <blockquote> <p>Vielleicht willst Du das Passwort ja auf deinem alten Fernschreiber drucken?</p> </blockquote> <p><a href="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png?size=medium" alt="ITA2" title="Lochstreifen ITA2" loading="lazy"></a></p> </blockquote> <p>wenn man die Löcher in eine Karte stanzt, kann man es als „Token-Lochkarte“ ähnlich einer Smartcard verwenden.</p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784754#m1784754 dedlfix 2021-02-23T22:27:10Z 2021-02-23T22:27:10Z Reihenfolge beim Überprüfen neuer Passwörter <p>Tach!</p> <blockquote> <p>Ich habe das gerade mal ausprobiert. Laut Doku liefert password_hash ja FALSE, wenn ein Fehler auftritt.</p> </blockquote> <p>Du testest mit PHP 7? Teste mal mit PHP 8, da gibt es nicht nur eine Warnung.</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784757#m1784757 Rolf B 2021-02-24T07:17:36Z 2021-02-24T07:17:36Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo dedlfix,</p> <p>sehr schön, dass PHP so langsam typsicherer wird.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784924#m1784924 1unitedpower 2021-02-27T11:58:56Z 2021-02-27T11:58:56Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <p>sehr schön, dass PHP so langsam typsicherer wird.</p> </blockquote> <p>Wenn es etwas mehr sein darf, kann ich <a href="https://github.com/phan/phan" rel="noopener noreferrer">phan</a> empfehlen. Das ist ein Typchecker und ein statisches Analysetool aus der Feder von PHP-Erfinder Rasmus Lerdorf. phan geht über das PHP-interne Typsystem hinaus und erlaubt bspw. auch Generics, aka. parametrischer Polymorphismus.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784764#m1784764 Tabellenkalk 2021-02-24T08:09:47Z 2021-02-24T08:09:47Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo,</p> <blockquote> <p>Passwörter sollten für den Nutzer kein Ärgernis, sondern gut zu merken sein. Ich empfehle da immer den <a href="https://xkcd.com/936/" rel="nofollow noopener noreferrer">xkcd-Comic zur Passwortkomplexität</a>.</p> </blockquote> <p>Ich hab von der Theorie dahinter keine Ahnung, wo kommen die xx Bits of Entropy her? Wenn das mit den vier Worten wirklich empfehlenswert ist, dann fänd ich das echt gut!</p> <p>Gruß<br> Kalk</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784765#m1784765 Rolf B 2021-02-24T08:36:57Z 2021-02-24T09:19:44Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Tabellenkalk,</p> <p>letztlich geht es um die mögliche Anzahl von Passworten und damit Kombinatorik. Meine Eselsbrücke ist da immer "Symbolzahl" hoch "Stellen", d.h. wenn ich 7 Symbole habe und 4 Stellen, habe ich $$7^4=2401$$ mögliche Wörter, die ich damit bilden kann.</p> <p>Die Bitzahl der Entropie ist dann einfach der Exponent der Zweierpotenz, die diese Anzahl darstellt. Wenn ich die Anzahl kenne, muss ich also den Zweierlogarithmus dieser Anzahl bilden. Wenn man dafür keinen Rechner hat, kann man den Logarithmus zur Basis 2 oder e nehmen und die Umrechnungsformel verwenden: $$\displaystyle \log_2 a = \frac{\log_{10}a}{\log_{10}2}= \frac{\ln a}{\ln2}$$).</p> <p>Die Entropie einer Variation von Troubadour ist schwierig zu berechnen. Man muss von der Anzahl brauchbarer Wörter im Wörterbuch ausgehen - z.B. 100000. Die Betonung liegt auf „brauchbar“, also sind es vermutlich deutlich weniger. Der Zweierlogarithmus von 100000 ist 16,6. Das sind also 16,6 Bits Entropie. Hinzu kommen die Sonderzeichen und die Variationen von 1337-Speak, die man einbaut; die 28 Bits sind vermutlich ein "educated guess".</p> <p>Bei der Vierwort-Konstruktion ist es einfacher. Wähle ich ein Wort aus einer festgelegten Liste von 2048 Wörtern, sind das 11 Bits Entropie. Weil 2^11=2048. Wähle ich vier Wörter aus dieser Liste und lasse dabei auch Wiederholungen zu (correct correct correct correct), sind es gemäß der Eselsbrücke $$\displaystyle (2¹¹)^4 = 2^{44}$$ Möglichkeiten. Das Schöne daran ist, dass die Wortliste nicht geheim zu sein braucht.</p> <p>Lasse ich keine Wiederholungen zu, sinkt die Entropie nur minimal. Aus der Möglichkeitenzahl $$2^{44}$$ wird dann $$2048\cdot 2047\cdot 2046\cdot 2045$$, der Logarithmus dieses Produkts ist die Summe der Logarithmen der Faktoren, also $$43{,}996$$.</p> <p>Das gilt natürlich nur solange, wie man einen guten Zufallszahlengenerator hat und die ausgewürfelten Wörter auch wirklich vorurteilsfrei nimmt. Verwendet man einen primitiven <a href="https://de.wikipedia.org/wiki/Kongruenzgenerator" rel="nofollow noopener noreferrer">Kongruenzgenerator</a>, oder würfelt man solange, bis man eine „schöne“ Kombi bekommt, sinkt die Entropie deutlich, weil das Symbole oder Symbolkombinationen aus dem Möglichkeitsraum streicht, bzw. die möglichen Symbolfolgen begrenzt.</p> <p>Leider hat sich "correct horse battery staple" noch nicht bis zum BSI herumgesprochen. Die empfehlen nach wie vor den Tr0b4dur&9, und wie Randall anführt, führen Diskussionen über diese Idee mit denen, die das Thema nicht wirklich verstehen, schnell zu heißem Streit.</p> <p>Ich weiß allerdings selbst nicht so genau, ob ich beim Anmelden ständig <em>correct horse battery staple</em> tippen will, oder doch lieber nur 10 wilde Zeichen. Denn ich muss mich auf der Arbeit regelmäßig an verschiedenen Systemen anmelden; wir haben verschiedene Netzwerkdomänen und auch unterschiedliche User-IDs (für normale und Admintätigkeiten).</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784768#m1784768 Tabellenkalk 2021-02-24T09:11:45Z 2021-02-24T09:11:45Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo,</p> <p>vielen Dank für die Erläuterung!</p> <p>Also ist der korrekte Pferdebatteriestapel zwar sicherer aber nicht praktikabel, denn einerseits hat man viel mehr zu tippen und andererseits enthält er kein Sonderzeichen o.ä. was von manchen Logins vorgeschrieben wird…</p> <p>Gruß<br> Kalk</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784778#m1784778 Rolf B 2021-02-24T11:44:28Z 2021-02-24T11:44:28Z Aufteilung der Funktion, MVC <p>Hallo localhorst,</p> <p>wir wissen nicht, ob Vapita MVC verwendet bzw. schonmal was davon gehört hat. Aber wenn wir ein MVC-Design voraussetzen, dann würde sich das so aufteilen:</p> <ul> <li> <p>Übernehmen der Formdaten, ggf. auch grundsätzliche Validierung (Array/String, steht was drin) ist Teil der View-Schicht. Die View-Schicht besteht aus zwei Teilen: Zum einen der Webbrowser, und zum anderen der serverseitige Code zum Senden an den und Empfangen vom Browser. Da jeder Request jungfräulich am Server beginnt, ist es Sache des verwendeten Controllers, die Übernahme der Eingabedaten zu orchestrieren. Das ist meistens so gebaut, dass der Controller die Übertragung der Daten ins Modell direkt durchführt, aber <strong>eigentlich</strong> ist es Teil der View-Schicht. Wenn ich also einen LoginView auf dem Browser habe und der sich zurückmeldet, dann müsste der LoginController eigentlich User-Model und LoginView erzeugen, die beiden verkabeln und es dann dem View überlassen, $_GET und $_POST Daten auszuwerten (MVC Prinzip: Der View kennt das Model, aber das Model nicht den View. Der Controller kennt View und Model, aber beide kennen den Controller nicht).</p> </li> <li> <p>Speichern der Userdaten (Name, Passworthash, Rechte, bla bla) ist Teil des Model. Ihre Persistierung gehört in den DB-Layer, der von MVC nicht explizit erwähnt wird, aber Teil des Models ist. Der Modellschicht den passenden DB-Layer unterzuschieben sollte konfigurativ erfolgen, oder im Web zentral von der allgemeinen Requeststeuerung erledigt werden.</p> </li> <li> <p>Eine Passwortklasse ist eher auf der Controller-Ebene anzusiedeln, es ist eine Diensteklasse für die Aktionen Login, Register und ChangePassword des User-Controllers</p> </li> </ul> <p>Diskutieren kann man, ob eine Passwort-Klasse den Job haben sollte, einen User anzulegen (db_insert_password). Das gehört meiner Vorstellung nach anders sortiert, ich wollte nur die Diskussion nicht zu weit aufblähen und neue Themenfelder eröffnen. Ein User-Objekt hat einen Namen, einen Passworthash, Rechte, etc. Und ein Login-Controller verwendet die Passwort-Klasse, um Passwörter zu verschlüsseln und zu überprüfen. Den Hash bekommt er vom User geliefert. Beim Anlegen eines neuen Users oder beim Passwortwechsel kann der Hash natürlich auch geändert werden.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784769#m1784769 Rolf B 2021-02-24T09:45:17Z 2021-02-24T09:47:16Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Tabellenkalk,</p> <blockquote> <p>was von manchen Logins vorgeschrieben wird…</p> </blockquote> <p>Was auch an der <a href="https://www.bsi.bund.de/DE/Themen/Verbraucherinnen-und-Verbraucher/Informationen-und-Empfehlungen/Cyber-Sicherheitsempfehlungen/Accountschutz/Sichere-Passwoerter-erstellen/sichere-passwoerter-erstellen_node.html" rel="nofollow noopener noreferrer">Empfehlung des BSI für sichere Passwörter liegt</a>. Randall kämpft mit diesem Vorschlag gegen Windmühlen an.</p> <p>Oh. Update. Sie haben das aktualisiert, es stehen jetzt auch "lange Passworte mit 2 Zeichenarten, z.B. mehrere Wörter" auf der Liste.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784772#m1784772 Rolf B 2021-02-24T11:02:10Z 2021-02-24T11:02:10Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <p>schön, dass Du deinen Code säubern und strukturieren möchtest.</p> <p>Aber der Meckerfritze ist wieder da </p> <p>Ich habe dein Array/String Konzept noch nicht verstanden. Mal gehst Du die Array-Einträge durch, mal nimmst Du nur den ersten Eintrag. Ich hoffe, dein um ein Vierteljahr älteres Ich (dein schärfster Kritiker überhaupt) wird Dich dafür nicht hassen.</p> <p>Ich glaube, du hast jetzt ganz allgemein versucht, Arrays zu behandeln. Hast Du Dir vorab Gedanken gemacht, ob ein Array als Input für diese Klasse überhaupt irgendwie sinnvoll ist und welchen sinnvollen Umgang es damit geben sollte? Arrays in $_POST kommen ja nur vor, wenn Du das im Form so vorsiehst, oder Dir irgendwer das bösartig hineinpostet. Heißt: Wenn Du vorhast, in deinem Login- oder Register-Form Passwort-Arrays einzubauen, dann überlege Dir, wie Du damit umgehen müsstest. Wenn Du das nicht vorhast, weise sie als manipulierte Eingabe zurück.</p> <p>Methode hash:</p> <ul> <li>(is_array(...)) muss man nicht extra klammern.</li> <li>array_pop kann fehlschlagen, wenn das Array leer ist</li> <li>ist es tatsächlich sinnvoll, wenn hash nur den ersten Array-Eintrag hasht, wenn es ein Array bekommt? Könnte es nicht auch sinnvoll sein, jeden Eintrag einzeln zu hashen und ein Array aus Hashes zurückzugeben? Aber das hängt vom Grundkonzept für Arrays ab, siehe oben.</li> </ul> <p>Methode verify:</p> <ul> <li>An sich okay, aber sie kann nicht mit Arrays umgehen. Konzept?</li> </ul> <p>Methode isString:</p> <ul> <li>Ist falsch. Gib ihr ARRAY(1,2,"Hallo") als Eingabe und sie sagt TRUE. Gib ihr ARRAY(1,"Hallo",3) als Eingabe und sie sagt FALSE. Weil sie immer das Ergebnis für den letzten Eintrag zurückgibt.</li> <li>Ist ungeschickt. Es freut mich ja, dass Du Dich in den null coalesce Operator <code>??</code> verliebt hast, aber man braucht ihn nur dort, wo NULL auch wirklich vorkommen kann. Deine Array-Prüfung soll vermutlich eine "ist alles ein String" Prüfung durchführen. Dafür setzt man $passwordIsString <strong>vor</strong> der Schleife auf TRUE und in der Schleife schaut man, ob ein Eintrag ein Nicht-String ist. Wenn ja, setzt man $passwordIsString auf FALSE und bricht mit break aus der Schleife aus.</li> <li>Null Coalescing braucht man in dieser Methode nirgends. Auch im else-Zweig nicht. Die PHP Doku sagt, dass is_string <strong>immer</strong> einen booleschen Wert liefert, niemals NULL.</li> </ul> <p>Methode isEqual:</p> <ul> <li>Der <code>==</code> oder <code>===</code> Operator liefern immer ein bool. ?? ist unnötig.</li> <li>Kleinigkeit: Hier wäre ein typsicherer Vergleich mit <code>===</code> besser. Es wird wohl auch mit <code>==</code> funktionieren, weil Du vorher auf Strings testest.</li> </ul> <p>Methode hasMinLength:</p> <ul> <li>Array-Konzept...</li> <li>?? unnötig, > liefert immer einen bool</li> </ul> <p>Methode isComplex:</p> <ul> <li>Array-Konzept...</li> <li>Ein Konstrukt der Art (bedingung) ? true : false ist redundant, es sei denn, die Bedingung liefert auch mal was anderes als einen booleschen Wert. Das ist bei preg_match tatsächlich der Fall, es liefert 1 für "gefunden" oder 0 für "nicht gefunden", und FALSE für "da ging was schief". Schief gehen kann aber nur der Fall, dass deine Regex falsch ist. Ich finde, du solltest FALSE separat prüfen (mit ===, um es von 0 unterscheiden zu können) und dann einen Error loggen.</li> </ul> <p>Sorry für die lange Liste...</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784775#m1784775 Der Martin 2021-02-24T11:34:02Z 2021-02-24T11:34:02Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <blockquote> <p>Ich hoffe, dein um ein Vierteljahr älteres Ich (dein schärfster Kritiker überhaupt)</p> </blockquote> <p>das lese oder höre ich immer wieder - und kann es doch selbst nicht nachvollziehen.</p> <p>Wenn ich heute meinen eigenen Code von vor einem halben Jahr, oder auch von vor zehn Jahren ansehe, dann fällt mir zwar manchmal auf: "Das würde ich heute anders lösen."<br> Aber es ist sehr, sehr selten so, dass ich nicht mehr verstehe, was ich damals getan habe. Je nach Komplexität des Codes brauche ich normalerweise zwischen einer halben Stunde und einem halben Tag, bis ich wieder komplett "im Fluss" bin.</p> <p>Und ich behaupte: Dazu tragen maßgeblich eine übersichtliche Strukturierung, sinnvoll gewählte sprechende Bezeichner und informative Kommentare bei.</p> <p>Deswegen kann ich nur immer wieder jedem empfehlen: Investiert ruhig eine Stunde mehr Zeit, um den Code sauber zu form(ul|at)ieren und zu dokumentieren, das zahlt sich später aus.</p> <p>Live long and <s>pros</s> healthy,<br>  Martin</p> <div class="signature">-- <br> Lasst uns ins Horn brechen und aufstoßen. Höchste Zeit, auf den Weg zu machen.<br> (mit freundlichem Dank an <a href="https://forum.selfhtml.org/self/2021/feb/20/telefonbuch-ruckwartssuche/1784617#m1784617" rel="noopener noreferrer">Tabellenkalk</a> für die Ergänzung ) </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784842#m1784842 vapita 2021-02-25T06:33:45Z 2021-02-25T06:33:45Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <p>habe deinen Post erst eben gesehen. Ich danke dir für deine großartige Antwort. Ich brauche noch ein wenig Zeit, um es umzusetzen.</p> <p>Bis später und beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784843#m1784843 vapita 2021-02-25T08:00:17Z 2021-02-25T08:00:17Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <blockquote> <p>Aber der Meckerfritze ist wieder da </p> </blockquote> <p>So soll es aber auch sein. Schließlich wächst man nicht am Lob, sondern an der Kritik. Besonders, wenn sie so konstruktiv ist.</p> <blockquote> <p>Arrays in $_POST kommen ja nur vor, wenn Du das im Form so vorsiehst, oder Dir irgendwer das bösartig hineinpostet. Heißt: Wenn Du vorhast, in deinem Login- oder Register-Form Passwort-Arrays einzubauen, dann überlege Dir, wie Du damit umgehen müsstest. Wenn Du das nicht vorhast, weise sie als manipulierte Eingabe zurück.</p> </blockquote> <p>Grundsätzlich kommen vom Form nur Strings an, jedoch habe ich im Controller das Passwort und das Kontrollpasswort in ein Array gesetzt, da ich das so übersichtlicher fand.</p> <blockquote> <p>Methode hash:</p> </blockquote> <p>Die Methode nutze ich erst nach der Passwortvalidierung, da kommt nun gar nicht erst ein Array an:</p> <pre><code class="block language-php"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">hash</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$plain_password</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">string</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token constant">PASSWORD_DEFAULT</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>und das User-Objekt macht dann vor dem Speichern in der Datenbank:</p> <pre><code class="block language-php"><span class="token comment"># Entity/User.php</span> <span class="token operator">...</span> <span class="token keyword">return</span> <span class="token class-name static-context">PasswordService</span><span class="token operator">::</span><span class="token function">hash</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">...</span> </code></pre> <blockquote> <p>Methode verify:</p> </blockquote> <p>Diese Methode kommt dann erst beim Login zum Einsatz:</p> <pre><code class="block language-php"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">verify</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token keyword type-hint">string</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">bool</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_verify</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <p>Methode isString:</p> </blockquote> <p>Kommt das Passwort als Array (Passwort und Kontrollpasswort), soll jedes auf String überprüft werden.</p> <pre><code class="block language-php"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">isString</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">bool</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token keyword">empty</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$passwordIsString</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <p>Methode isEqual:</p> </blockquote> <pre><code class="block language-php"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">isEqual</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">bool</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <p>Methode hasMinLength:</p> </blockquote> <p>Hier reicht es, meiner Meinung nach, nur das Passwort auf Länge zu prüfen, da das Kontrollpasswort sowieso identisch sein muss.</p> <pre><code class="block language-php"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">hasMinLength</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">bool</span> <span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token keyword">empty</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">strlen</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <p>Methode isComplex:</p> </blockquote> <p>Hier soll auch nur das Passwort, nicht das Kontrollpasswort, sollte es sich um ein Passwort-Array handeln, überprüft werden. Bin mir noch nicht sicher, ob ich das so richtig gemacht habe:</p> <pre><code class="block language-php"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">bool</span> <span class="token punctuation">{</span> <span class="token keyword">try</span><span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token keyword">empty</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token variable">$pregMatch</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">preg_match</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/^(?=.*\d)(?=.*[@#\-_$%^&+=§!\?])(?=.*[a-z])(?=.*[A-Z])[0-9A-Za-z@#\-_$%^&+=§!\?]{8,20}$/'</span><span class="token punctuation">,</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token constant boolean">false</span> <span class="token operator">===</span> <span class="token variable">$pregMatch</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$pregMatch</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$exception</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Logger</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">newMessage</span><span class="token punctuation">(</span><span class="token variable">$exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Logger</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">customErrorMsg</span><span class="token punctuation">(</span><span class="token variable">$exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <blockquote> <p>Sorry für die lange Liste...</p> </blockquote> <p>ich kann mich nur für die Unterstzütung und Mühe bedanken.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784777#m1784777 Tabellenkalk 2021-02-24T11:43:48Z 2021-02-24T11:43:48Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo,</p> <blockquote> <p>Was kommt raus, wenn man</p> <p><code>var_dump("□□□□□□□□"=="00000000");</code><br> oder<br> <code>var_dump("□□□□□□□□"==="00000000");</code><br> oder auch<br> linke und rechte Seite vertauscht.</p> <p>ausführt?</p> </blockquote> <p>Merkwürdige Frage, auch wenn ich das jetzt neugierigerweise tatsächlich getestet habe. Was soll da anderes als <code>False</code> rauskommen?</p> <p>Hast du Anlass zu erwarten, dass da <code>True</code> kommen könnte?</p> <p>Gruß<br> Kalk</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784779#m1784779 dedlfix 2021-02-24T11:45:00Z 2021-02-24T11:45:00Z Reihenfolge beim Überprüfen neuer Passwörter <p>Tach!</p> <blockquote> <p>Ich habe leider kein php zur Verfügung im Moment.</p> </blockquote> <p>Teste es doch mit der <a href="https://sandbox.onlinephpfunctions.com/" rel="nofollow noopener noreferrer">PHP Sandbox</a>.</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784780#m1784780 Rolf B 2021-02-24T11:45:13Z 2021-02-24T11:45:43Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo localhorst,</p> <p>hier ist eins, mit vielen Versionen zur Auswahl:</p> <p><a href="https://sandbox.onlinephpfunctions.com/" rel="nofollow noopener noreferrer">https://sandbox.onlinephpfunctions.com/</a></p> <p>Edit: Verd*mmt, Dedlfix war im Fotofinish schneller.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784782#m1784782 TS ts-self@online.de https://bitworks.de 2021-02-24T12:03:43Z 2021-02-24T12:03:43Z == oder === ? <p>Hello WAN-Horst, ;-P</p> <blockquote> <blockquote> <blockquote> <ol start="2"> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> </ol> </blockquote> <p>Warum typsicher? $_POST liefert Strings oder Arrays. Strings mit Arrays zu vergleichen liefert false. Gleiche Arrays liefern true, egal ob typsicher oder nicht. Der typsichere Vergleich ergibt keinen Unterschied zum nicht typsicheren und der unerlaubte Fall Array wird nicht bemerkt. Es ist hier also egal, ob typsicher verglichen wird oder nicht.</p> </blockquote> <p>Was kommt raus, wenn man</p> <p><code>var_dump("□□□□□□□□"=="00000000");</code><br> oder<br> <code>var_dump("□□□□□□□□"==="00000000");</code><br> oder auch<br> linke und rechte Seite vertauscht.</p> <p>ausführt? Die Kästchen sollen Leerzeichen sein.</p> <p>Ich habe leider kein php zur Verfügung im Moment.</p> </blockquote> <p>Ich habe auch nur Version (7.4.5):</p> <p>Interessant ist diese Variante:</p> <pre><code class="block language-php"> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">==</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">===</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>ergibt</p> <pre><code class="block language-text"> bool(true) bool(false) </code></pre> <p><strong>Der Identitätsoperator erscheint mir daher doch richtig zu sein!</strong></p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784781#m1784781 Der Martin 2021-02-24T11:47:05Z 2021-02-24T11:47:05Z Reihenfolge beim Überprüfen neuer Passwörter <p>Mahlzeit,</p> <blockquote> <blockquote> <p><code>var_dump("□□□□□□□□"=="00000000");</code><br> oder<br> <code>var_dump("□□□□□□□□"==="00000000");</code><br> oder auch<br> linke und rechte Seite vertauscht.</p> </blockquote> <p>Merkwürdige Frage, auch wenn ich das jetzt neugierigerweise tatsächlich getestet habe. Was soll da anderes als <code>False</code> rauskommen?</p> </blockquote> <p>ich habe tatsächlich auch leichte Zweifel gehabt.</p> <blockquote> <p>Hast du Anlass zu erwarten, dass da <code>True</code> kommen könnte?</p> </blockquote> <p>Ja. PHP konvertiert manchmal unerwartet Strings in Numbers. Dabei können seltsame Ergebnisse entstehen - hier beispielsweise, weil sowohl ein String aus ein paar Blanks, als auch ein String mit ein paar Nullen auf den Zahlenwert 0 abgebildet wird. Ein <em>true</em> beim nicht typsicheren Vergleich hätte mich daher nicht gewundert.</p> <p>Live long and <s>pros</s> healthy,<br>  Martin</p> <div class="signature">-- <br> Lasst uns ins Horn brechen und aufstoßen. Höchste Zeit, auf den Weg zu machen.<br> (mit freundlichem Dank an <a href="https://forum.selfhtml.org/self/2021/feb/20/telefonbuch-ruckwartssuche/1784617#m1784617" rel="noopener noreferrer">Tabellenkalk</a> für die Ergänzung ) </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784801#m1784801 vapita 2021-02-24T14:39:41Z 2021-02-24T14:39:41Z Aufteilung der Funktion, MVC <p>Hallo an alle,</p> <p>ja, ich nutze das MVC-Pattern. Ich habe für User-Angelegenheiten einen sogenannten <strong>UserController</strong> erstellt, der derzeit die Methoden:</p> <ul> <li>index</li> <li>login</li> <li>logout</li> <li>register</li> </ul> <p>enthält. Weitere Methoden folgen noch. Etwa für das Aktualisieren der Benutzerdaten. Eben dann auch etwa das Erneuern des Passworts. Ich habe sämtliche Passwortvalidierungen in eine <strong>Passwort-Klasse</strong> gepackt und diese dann vom Controller aus aufgerufen. Das müllt mir mir dann aber immer noch den Controller zu sehr voll, weswegen ich zusätzlich noch eine <strong>User-Klasse</strong> erstellt habe, von der aus auch die Passwortvalidierungen durchgeführt werden.</p> <p>Die User-Klasse und die Passwort-Klasse würde ich als Services unterhalb des Controllers ansiedeln. Der Controller selbst steuert dann, was die View ausgibt oder von dort kommt. (z.B. Formulardaten und Fehlermeldungen). Außerdem steuert er auch, was er vom Model haben will oder was das Model speichern soll.</p> <p>Nun muss ich erstmal den UserController aufräumen. Gewisse Tests aus der Passwort-Klasse können ja auch für E-Mail-Adressen, Benutzernamen oder sonstiges verwendet werden. Da kommt dann der UserService ins Spiel, der allgemeine Abfragen erledigt.</p> <p>Gern melde ich mich später mit dem Ergebnis zurück.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784783#m1784783 localhorst 2021-02-24T12:07:40Z 2021-02-24T12:07:40Z == oder === ? <p>Hallo TS,<br> hallo Alle,</p> <blockquote> <blockquote> <blockquote> <blockquote> <ol start="2"> <li>Übereinstimmung prüfen (<a href="https://www.php.net/manual/de/language.operators.comparison.php" rel="nofollow noopener noreferrer">===, identisch</a>)</li> </ol> </blockquote> <p>Warum typsicher? $_POST liefert Strings oder Arrays. Strings mit Arrays zu vergleichen liefert false. Gleiche Arrays liefern true, egal ob typsicher oder nicht. Der typsichere Vergleich ergibt keinen Unterschied zum nicht typsicheren und der unerlaubte Fall Array wird nicht bemerkt. Es ist hier also egal, ob typsicher verglichen wird oder nicht.</p> </blockquote> <p>Was kommt raus, wenn man</p> <p><code>var_dump("□□□□□□□□"=="00000000");</code><br> oder<br> <code>var_dump("□□□□□□□□"==="00000000");</code><br> oder auch<br> linke und rechte Seite vertauscht.</p> <p>ausführt? Die Kästchen sollen Leerzeichen sein.</p> <p>Ich habe leider kein php zur Verfügung im Moment.</p> </blockquote> <p>Ich habe auch nur Version (7.4.5):</p> <p>Interessant ist diese Variante:</p> <pre><code class="block language-php"> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">==</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">===</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>ergibt</p> <pre><code class="block language-text"> bool(true) bool(false) </code></pre> <p><strong>Der Identitätsoperator erscheint mir daher doch richtig zu sein!</strong></p> </blockquote> <p>Na hoppla!<br> Danke für den Test.</p> <p>Da schlägt dann wohl die Typumwandlung zu?<br> Ist ja ne echt böse Falle!</p> <p>♡♡♡ ♡♡♡ ♡♡♡ ♡♡♡<br> Hinweis:<br> Meine Antworten beziehen sich (meistens) auf den gesamten bisherigen Thread. Der/die jeweilige direkte Vorposter/in sollte sich daher nicht alleine angesprochen fühlen.<br> ♡♡♡ ♡♡♡ ♡♡♡ ♡♡♡</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784789#m1784789 Rolf B 2021-02-24T12:40:28Z 2021-02-24T12:40:28Z == oder === ? <p>Hallo TS,</p> <p>PHP nennt das <a href="https://www.php.net/manual/en/language.types.numeric-strings.php" rel="nofollow noopener noreferrer">Numeric Strings</a></p> <p>Ein Punkt für Kollege Bastelstube. PHP ist grottig, es bräuchte wie JavaScript einen "Strict Mode", der all diese hysterisch gewachsenen Quirks abschaltet.</p> <p>Deswegen gleich das Büßerhemd anzuziehen, sich den Knotenstrick ums Bein zu schnüren und Perl zu nehmen scheint mir aber doch übertrieben.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784792#m1784792 dedlfix 2021-02-24T12:57:01Z 2021-02-24T12:57:01Z == oder === ? <p>Tach!</p> <blockquote> <p>Interessant ist diese Variante:</p> <pre><code class="block language-php"> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">==</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">===</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>ergibt</p> <pre><code class="block language-text"> bool(true) bool(false) </code></pre> <p><strong>Der Identitätsoperator erscheint mir daher doch richtig zu sein!</strong></p> </blockquote> <p>Gut, einen Punkt für den ===. Aber dann ist da immer noch Punkt 3 und 4b, an dem die Prüfung scheitert.</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784784#m1784784 TS ts-self@online.de https://bitworks.de 2021-02-24T12:14:59Z 2021-02-24T13:17:39Z == oder === ? <p>Hello Horst,</p> <blockquote> <blockquote> <p>Ich habe auch nur Version (7.4.5):</p> <p>Interessant ist diese Variante:</p> <pre><code class="block language-php"> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">==</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">===</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>ergibt</p> <pre><code class="block language-text"> bool(true) bool(false) </code></pre> <p><strong>Der Identitätsoperator erscheint mir daher doch richtig zu sein!</strong></p> </blockquote> <p>Na hoppla!<br> Danke für den Test.</p> <p>Da schlägt dann wohl die Typumwandlung zu?<br> Ist ja ne echt böse Falle!</p> </blockquote> <p>Ja. Und genau diese Lücke hatte ich auch im Hinterhirn, bis <a href="/users/27" class="mention registered-user" rel="noopener noreferrer">@dedlfix</a> mich dann in die Irre geführt hat ;-(</p> <p>Ohne dein Nachquängeln hätte ich ihm blind vertraut. :-O</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784799#m1784799 kai345 2021-02-24T13:46:34Z 2021-02-24T13:54:00Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <p>Als Lochmuster hättest Du nun noch ein visuelles (also nicht codiertes) "selfHTML it toll" stanzen können ;-)</p> </blockquote> <p><a href="/images/a625c4c8-76a7-11eb-8f1a-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/a625c4c8-76a7-11eb-8f1a-b42e9947ef30.png?size=medium" alt="Visuelles SELFHTML IST TOLL in ITA2" title="QYX~|YY~|TT~|SS~| |~E|E~|> >|~|TT~~|~QYX~E|E~~E|E~|Z|~|TT~|TT" loading="lazy"></a></p> <div class="signature">-- <br> Stur lächeln und winken, Männer! </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784791#m1784791 TS ts-self@online.de https://bitworks.de 2021-02-24T12:53:46Z 2021-02-24T12:54:22Z == oder === ? <p>Hello,</p> <blockquote> <p>PHP nennt das <a href="https://www.php.net/manual/en/language.types.numeric-strings.php" rel="nofollow noopener noreferrer">Numeric Strings</a></p> </blockquote> <p>Ja danke.<br> Ich bin ja noch ganz neu hier (ca. seit 1999), da kann man sowas nicht wissen ;-P</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784793#m1784793 dedlfix 2021-02-24T13:01:13Z 2021-02-24T13:01:13Z == oder === ? <p>Tach!</p> <blockquote> <p>PHP nennt das <a href="https://www.php.net/manual/en/language.types.numeric-strings.php" rel="nofollow noopener noreferrer">Numeric Strings</a></p> </blockquote> <p>"When a string needs to be evaluated as number (e.g. arithmetic operations, int type declaration, etc.) …"</p> <p>Eigentlich werden hier zwei String verglichen und nicht String mit Zahl. Ich sehe da kein "needs to be evaluated as number". Das ist für mich eine unerwartete Typkonvertierung.</p> <p>dedlfix.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784794#m1784794 TS ts-self@online.de https://bitworks.de 2021-02-24T13:06:42Z 2021-02-24T13:08:05Z == oder === ? <p>Hello <a href="/users/27" class="mention registered-user" rel="noopener noreferrer">@dedlfix</a>,</p> <blockquote> <blockquote> <p>Interessant ist diese Variante:</p> <pre><code class="block language-php"> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">==</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"00"</span> <span class="token operator">===</span> <span class="token string double-quoted-string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>ergibt</p> <pre><code class="block language-text"> bool(true) bool(false) </code></pre> <p><strong>Der Identitätsoperator erscheint mir daher doch richtig zu sein!</strong></p> </blockquote> <p>Gut, einen Punkt für den ===. Aber dann ist da immer noch Punkt 3 und 4b, an dem die Prüfung scheitert.</p> </blockquote> <p>Es ist zudem ein Spezialfall, vermutlich an dieser Stelle der einzige. Aber ein einziger Spezialfall reicht i.d.R., um ein System kompromittieren zu können, egal ob willentlich oder unwissentlich.</p> <p>Wenn man das geplante Passwort-Modul als Ganzes betrachtet, wird die Lücke an der einen Stelle durch nachfolgende Prüfungen geschlossen. Wenn man aber nun - warum auch immer - einzelne Funktionen für andere Zwecke benutzt, dann kann das schon mächtig in die Hose gehen.</p> <h4>Darum immer meine Forderung:</h4><p>Jede Funktion muss <strong>genau das</strong> leisten, was man von ihr erwartet, nicht weniger und nicht mehr (also keine Seiteneffekte), egal, ob man sie einzeln oder im Verbund mit anderen verwendet.</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784795#m1784795 TS ts-self@online.de https://bitworks.de 2021-02-24T13:14:27Z 2021-02-24T13:14:27Z == oder === ? <p>Hello <a href="/users/27" class="mention registered-user" rel="noopener noreferrer">@dedlfix</a>,</p> <blockquote> <blockquote> <p>PHP nennt das <a href="https://www.php.net/manual/en/language.types.numeric-strings.php" rel="nofollow noopener noreferrer">Numeric Strings</a></p> </blockquote> <p>"When a string needs to be evaluated as number (e.g. arithmetic operations, int type declaration, etc.) …"</p> <p>Eigentlich werden hier zwei String verglichen und nicht String mit Zahl. Ich sehe da kein "needs to be evaluated as number". Das ist für mich eine unerwartete Typkonvertierung.</p> </blockquote> <p>Früher hieß das immer:<br> <em>Kommt immer darauf an, was links steht.</em></p> <p>Bei</p> <p><code>var_dump(0 == '000');</code></p> <p>hätte ich eine Typkonvertierung erwartet. Aber die Sache mit den Nullen-Strings ist schon lange bekannt und mMn ein schwerer logischer Bug.</p> <p>Sollte man da mal eine Message verfassen, oder ist das in PHP V8 sowieso Schnee von gestern?</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784797#m1784797 TS ts-self@online.de https://bitworks.de 2021-02-24T13:19:16Z 2021-02-24T13:23:34Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hello,</p> <blockquote> <blockquote> <blockquote> <p>Vielleicht willst Du das Passwort ja auf deinem alten Fernschreiber drucken?</p> </blockquote> <p><a href="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/e63ef9b0-761d-11eb-a965-b42e9947ef30.png?size=medium" alt="ITA2" title="Lochstreifen ITA2" loading="lazy"></a></p> </blockquote> <p>wenn man die Löcher in eine Karte stanzt, kann man es als „Token-Lochkarte“ ähnlich einer Smartcard verwenden.</p> </blockquote> <p>Wie jetzt? Darf man Smartcards lochen?</p> <p>Das erinnert mich an die Bilder von CDs, die jemand zum Abheften gelocht hatte. Leider wird Google auch immer humorloser, und ich fand die Bilder nicht mehr.</p> <p>Glück Auf<br> Tom vom Berg</p> <div class="signature">-- <br> Es gibt nichts Gutes, außer man tut es!<br> Das Leben selbst ist der Sinn. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784829#m1784829 MudGuard http://www.andreas-waechter.de/ 2021-02-24T17:00:57Z 2021-02-24T17:00:57Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hi,</p> <blockquote> <p>Das erinnert mich an die Bilder von CDs, die jemand zum Abheften gelocht hatte.</p> </blockquote> <p>Da waren die 3,5er Disketten praktischer, die waren schon im richtigen Abstand vorgelocht …</p> <p>cu,<br> Andreas a/k/a MudGuard</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784836#m1784836 Robert B. 2021-02-24T19:54:08Z 2021-02-24T19:54:08Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin Kai,</p> <blockquote> <blockquote> <p>Als Lochmuster hättest Du nun noch ein visuelles (also nicht codiertes) "selfHTML it toll" stanzen können ;-)</p> </blockquote> <p><a href="/images/a625c4c8-76a7-11eb-8f1a-b42e9947ef30.png" rel="noopener noreferrer"><img src="/images/a625c4c8-76a7-11eb-8f1a-b42e9947ef30.png?size=medium" alt="Visuelles SELFHTML IST TOLL in ITA2" title="QYX~|YY~|TT~|SS~| |~E|E~|> >|~|TT~~|~QYX~E|E~~E|E~|Z|~|TT~|TT" loading="lazy"></a></p> </blockquote> <p><em>das</em> wäre als Card ja mal richtig <em>smart</em> </p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784806#m1784806 localhorst 2021-02-24T15:01:28Z 2021-02-24T15:23:15Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo klawischnigg,<br> hallo Alle,</p> <blockquote> <p>Eines hast Du noch vergessen:</p> <p>Im RAM mit dem Mikroskop nachschauen, wie die beiden Passwörter auf Bit-Ebene ausschauen...</p> </blockquote> <p>Das hier ist für mich seit langem der lehrreichste Thread in Bezug auf Client-Server Webapplikationen. Ich finde es daher nicht angemessen, sachliche Postings und deren Urheber ins Lächerliche zu ziehen.</p> <blockquote> <p>(scnr)</p> </blockquote> <p>Das hilft dann auch nicht mehr.</p> <p>Oder kannst Du definitiv auf ein Speicherleck bei PHP in diesem Zusammenhang hinweisen? Dann würde ich mein Genöle sofort zurücknehmen und Dich um Verzeihung bitten.</p> <p>♡♡♡ ♡♡♡ ♡♡♡ ♡♡♡<br> Hinweis:<br> Meine Antworten beziehen sich (meistens) auf den gesamten bisherigen Thread. Der/die jeweilige direkte Vorposter/in sollte sich daher nicht alleine angesprochen fühlen.<br> ♡♡♡ ♡♡♡ ♡♡♡ ♡♡♡</p> <p>LG + Gesundheit<br> Localhorst</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784828#m1784828 vapita 2021-02-24T16:36:47Z 2021-02-24T16:36:47Z Aufteilung der Funktion, MVC <p>Hallo nochmal,</p> <p>Ich habe jetzt den <strong>UserController</strong> etwas aufgeräumt. Ich bin mir nicht sicher, ob man es so machen sollte, zumindest gab es nach einem ersten Test keine unerwarteten Fehler. Auszugsweise dazu einmal die <strong>register-Methode</strong>:</p> <pre><code class="block language-php"><span class="token comment"># UserController.php</span> <span class="token operator">...</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'302'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'base/index'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$userData</span> <span class="token operator">=</span> <span class="token constant">null</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">isPostRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">isFormSubmitted</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$userData</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token punctuation">[</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password_a'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password_b'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'firstname'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'firstname'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'lastname'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'lastname'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$userRepository</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getRepository</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">is_object</span><span class="token punctuation">(</span><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">user</span><span class="token operator">-></span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token variable">$userRepository</span><span class="token punctuation">,</span><span class="token variable">$userData</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$em</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getEntityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$em</span><span class="token operator">-></span><span class="token function">persist</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'302'</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'user/login'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">view</span><span class="token operator">-></span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user/register.html.twig'</span><span class="token punctuation">,</span><span class="token punctuation">[</span> <span class="token string single-quoted-string">'flash'</span> <span class="token operator">=></span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'user'</span> <span class="token operator">=></span> <span class="token variable">$userData</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">...</span> </code></pre> <p>Sobald das Registrierungsformular abgesendet wurde, startet die Überprüfung, andernfalls wird einfach nur das Formular präsentiert. In der IF-Abfrage wird zuerst das Array <strong>$userData</strong> mit den POST-Daten befüllt. Die Request-Methode <strong>getQuery()</strong> macht folgendes im Hintergrund:</p> <pre><code class="block language-php"><span class="token comment"># Request.php</span> <span class="token operator">...</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">getQuery</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$FormFieldName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$FormFieldName</span> <span class="token operator">!==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token function">filter_input</span><span class="token punctuation">(</span><span class="token constant">INPUT_POST</span><span class="token punctuation">,</span> <span class="token variable">$FormFieldName</span><span class="token punctuation">,</span> <span class="token constant">FILTER_SANITIZE_STRIPPED</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">query</span> <span class="token operator">=</span> <span class="token variable">$query</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Exception</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">newMessage</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">customErrorMsg</span><span class="token punctuation">(</span><span class="token variable">$query_exception</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">...</span> </code></pre> <p>Dann beginnt die eigentliche Prüfung in der User-Klasse von der aus auch das Passwort überprüft wird:</p> <pre><code class="block language-php"><span class="token comment"># User.php</span> <span class="token keyword">class</span> <span class="token class-name-definition class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">/** * @var Password */</span> <span class="token keyword">public</span> <span class="token class-name type-declaration">Password</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token comment">/** * User constructor. */</span> <span class="token keyword">function</span> <span class="token function-definition function">__construct</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">password</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Password</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $user // User-Objekt, dass die Datenbanktabelle widerspiegelt * @param $repository // Model-Repository, das die Methoden zum Abrufen enthält * @param array $data // Formulardaten, die per POST übergeben worden sind * @return int|mixed // Gibt entweder Fehlercode oder das User-Objekt zurück */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">validate</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token variable">$repository</span><span class="token punctuation">,</span> <span class="token keyword type-hint">array</span> <span class="token variable">$data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$usernameLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isString</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21031</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$usernameLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$usernameLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isUnique</span><span class="token punctuation">(</span><span class="token variable">$repository</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21011</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$usernameLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$emailLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isUnique</span><span class="token punctuation">(</span><span class="token variable">$repository</span><span class="token punctuation">,</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21012</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$emailLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$emailLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isEmail</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21022</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$emailLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$passwordLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">password</span><span class="token operator">-></span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$passwordLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$firstnameLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isString</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'firstname'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21034</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$firstnameLastError</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token variable">$lastnameLastError</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isString</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'lastname'</span><span class="token punctuation">,</span><span class="token variable">$data</span><span class="token punctuation">,</span><span class="token number">21035</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token variable">$lastnameLastError</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setUsername</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'username'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setEmail</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">password</span><span class="token operator">-></span><span class="token function">hash</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setFirstname</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'firstname'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setLastname</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'lastname'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setIsActive</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">setISBlocked</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token variable">$user</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $repository * @param $needle * @param $array * @param int $errorCode * @return int|mixed */</span> <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">isUnique</span><span class="token punctuation">(</span><span class="token variable">$repository</span><span class="token punctuation">,</span> <span class="token variable">$needle</span><span class="token punctuation">,</span> <span class="token variable">$array</span><span class="token punctuation">,</span> <span class="token variable">$errorCode</span> <span class="token operator">=</span> <span class="token number">2101</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$repository</span><span class="token operator">-></span><span class="token function">findOneBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token variable">$needle</span> <span class="token operator">=></span> <span class="token variable">$array</span><span class="token punctuation">[</span><span class="token variable">$needle</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token variable">$errorCode</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $needle * @param $array * @param int $errorCode * @return int|mixed */</span> <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">isEmail</span><span class="token punctuation">(</span><span class="token variable">$needle</span><span class="token punctuation">,</span> <span class="token variable">$array</span><span class="token punctuation">,</span> <span class="token variable">$errorCode</span> <span class="token operator">=</span> <span class="token number">2102</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">filter_var</span><span class="token punctuation">(</span><span class="token variable">$array</span><span class="token punctuation">[</span><span class="token variable">$needle</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">FILTER_VALIDATE_EMAIL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token variable">$errorCode</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $needle * @param $array * @param int $errorCode * @return int|mixed */</span> <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">isString</span><span class="token punctuation">(</span><span class="token variable">$needle</span><span class="token punctuation">,</span> <span class="token variable">$array</span><span class="token punctuation">,</span> <span class="token variable">$errorCode</span> <span class="token operator">=</span> <span class="token number">2103</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$array</span><span class="token punctuation">[</span><span class="token variable">$needle</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token variable">$errorCode</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Die Passwort-Klasse sieht nun so aus:</p> <pre><code class="block language-php"><span class="token comment"># Password.php</span> <span class="token keyword">class</span> <span class="token class-name-definition class-name">Password</span> <span class="token punctuation">{</span> <span class="token comment">/** * @param $plain_password * @return false|string|null */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$plain_password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$plain_password</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">password_hash</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token constant">PASSWORD_DEFAULT</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param string $plain_password * @param string $correct_hash * @return bool */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">verify</span><span class="token punctuation">(</span><span class="token keyword type-hint">string</span> <span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token keyword type-hint">string</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">password_verify</span><span class="token punctuation">(</span><span class="token variable">$plain_password</span><span class="token punctuation">,</span> <span class="token variable">$correct_hash</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param array $password * @return int */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">validate</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token keyword return-type">int</span> <span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isString</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1601</span><span class="token punctuation">;</span> <span class="token comment">// kein String</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isEqual</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1602</span><span class="token punctuation">;</span> <span class="token comment">// stimmt nicht überein</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">hasMinLength</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1603</span><span class="token punctuation">;</span> <span class="token comment">// ist nicht lang genug</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isAllowed</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1604</span><span class="token punctuation">;</span> <span class="token comment">// verwendet nicht erlaubte Zeichen</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1605</span><span class="token punctuation">;</span> <span class="token comment">// ist nicht komplex genug</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// alles in Ordnung</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isString</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$passwordIsString</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param array $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isEqual</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">hasMinLength</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">strlen</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isAllowed</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// TODO: auf erlaubte Zeichen prüfen</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @param $password * @return bool */</span> <span class="token keyword">private</span> <span class="token keyword">function</span> <span class="token function-definition function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token comment">/** Das Passwort muss mindestens * - einen Kleinbuchstaben, * - einen Großbuchstaben, * - eine Ziffer und * - ein Sonderzeichen @#-_$%^&+=§!? * enthalten. * Das Passwort muss zwischen 8 und 20 Zeichen lang sein. */</span> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token function">preg_match</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/^(?=.*\d)(?=.*[@#\-_$%^&+=§!\?])(?=.*[a-z])(?=.*[A-Z])[0-9A-Za-z@#\-_$%^&+=§!\?]{8,20}$/'</span><span class="token punctuation">,</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">?</span> <span class="token constant boolean">true</span> <span class="token punctuation">:</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Hab ich da noch etwas gravierendes verkehrt gemacht oder könnte man es im groben und ganzen so stehen lassen?</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784856#m1784856 Peter Pan (no reg.) 2021-02-25T12:39:38Z 2021-02-25T12:39:38Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hi,</p> <blockquote> <p><a href="https://home.fastix.org/Tests/PWForm/" rel="nofollow noopener noreferrer">https://home.fastix.org/Tests/PWForm/</a> (Die Dateien mit der Endung '.txt' kann man sich anschauen.)</p> </blockquote> <p>Nur aus Neugier: warum nicht als *.phps?</p> <div class="signature">-- <br> off: pp </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784918#m1784918 Raketenlagermeister 2021-02-27T10:27:17Z 2021-02-27T10:27:17Z Frage zu Mozillas „sicheres Passwort“ und Update <p><strong>1. Frage:</strong></p> <p>Kann man irgendwie mit JS feststellen, ob der Benutzer z.B. dem Vorschlag des Mozillas für ein „sicheres Passwort“ gefolgt ist?</p> <p><strong>2. Die Demo hat ein paar Updates bekommen:</strong></p> <p>Zuerst einmal wird die „Kompliziertsanforderungen“ des Passwort clientseitig geprüft. Die „Kompliziertsanforderungen“ diskutiere ich nicht, weil diese Geschäftspolitik sind. Im Beispiel ist es: 8 Zeichen lang, Große (A-Z) und kleine (a-z) Buchstaben drin, außerdem Ziffern und „Sonderzeichen“ (Achtung: Umlaute gelten als solche)</p> <p>Geprüft wird zunächst browserseitig mit den HTML5-Methoden (regulärer Ausdruck). Sind diese nicht verfügbar alternativ mit Javascript.</p> <p>Auf jeden Fall wird nach der Prüfung der „Kompliziertsanforderungen" die Übereinstimmung mit Javascript geprüft und ggf. der Button, der den Request auslösen soll, bei durchweg positiven Tests aktiviert. (Bei deaktivierten Javascript bleibt der Button aktiv, ggf. greift dann noch HTML5 ein wenn die Anforderungen nicht erfüllt sind.)</p> <p>Serverseitig wird nach Empfang nochmals geprüft ob die Passwörter kompliziert genug sind und ob diese übereinstimmen. Schließlich weiss niemand ob der Benutzer einen Browser benutzt oder etwas wie wget, curl und co.</p> <p>Ergänzt habe ich eine Möglichkeit, sich die Inhalte der Passwortfelder für eine konfigurierbare Zeitspanne anzusehen.</p> <p>Was nach wie vor nicht in dem Skript steht ist die nachfolgende Verwendung des positiv erkannten Passworts. Klar ist, dass hier die password_* Funktionen verwendet werden sollten. Allerdings sollte anno 2021 überlegt werden, ob man noch eine zweite Sicherheitsstufe einbaut (z.B. Versand eines geheimen, zufälligen Bestätigungs-Tokens an eine Telefonnummer (SMS), per Mail oder mit einem anderen Dienst) und Abfrage des Tokens über die Webseite. Das ist aber Geschäftspolitik und nicht Gegenstand meiner Betrachtungen.</p> <p><strong>Was nach wie vor gilt:</strong> Das ist nur Zeug, welches auf meiner „Festplatte“ herumlag. Es funktioniert und genügt als Demo oder Denkansatz - ist aber vom Verwender so umzubauen, dass es zu seinem Projekt passt (z.B. hinsichtlich der Lagerstätte der Voreinstellungen, weiterer Formular-Felder für Benutzername, Telefonnummer, Mailadresse und so weiter).</p> <p>Im Übrigen verzichte ich auf Tests, ob denn irgendetwas anderes als Text übertragen wurde. Grund: „Wer sowas einträgt kann sich später auch gerne damit anmelden…“. Außerdem sind genug Funktionen (trim!) drin, die für eine „sonstwas zu String“-Konvertierung sorgen und entweder zu einem hartem Fehler oder zu einem leerem Ergebnis und damit zur Ungültigkeit und ergo zum Abbruch führen.</p> <p>Warum <code>trim()</code>? Manche kopieren das Passwort aus einer Liste. Da könnten Spaces oder Zeilenumbrüche am Anfang oder Ende in die Eingabe geraten.</p> <p>Die Demo:</p> <blockquote> <p><a href="https://home.fastix.org/Tests/PWForm/" rel="nofollow noopener noreferrer">https://home.fastix.org/Tests/PWForm/</a> (Die Dateien mit der Endung '.txt' kann man sich anschauen.)</p> <p>Testen:</p> <p><a href="https://home.fastix.org/Tests/PWForm/PWForm.php" rel="nofollow noopener noreferrer">https://home.fastix.org/Tests/PWForm/PWForm.php</a></p> <p>Das Hashen käme, wenn der Passwort-Check erfolgreich ist.</p> </blockquote> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784827#m1784827 klawischnigg 2021-02-24T16:23:39Z 2021-02-24T16:23:39Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hi there,</p> <blockquote> <blockquote> <p>Eines hast Du noch vergessen:</p> <p>Im RAM mit dem Mikroskop nachschauen, wie die beiden Passwörter auf Bit-Ebene ausschauen...</p> </blockquote> <p>Das hier ist für mich seit langem der lehrreichste Thread in Bezug auf Client-Server Webapplikationen. Ich finde es daher nicht angemessen, sachliche Postings und deren Urheber ins Lächerliche zu ziehen.</p> </blockquote> <p>Ja, fein. Ich mach seit 20 Jahren Client-Server-Webapplikationen, und ich muß sagen, man kann halt alles übertreiben. Wenn ich jedes eingegeben Passwort auf seinen Zeichvorrat überprüft hätte, dann hätte ich dieses Posting, über das Du Dich so echauffierst, vermutlich nie geschrieben, denn dann wär' ich in der Zwischenzeit verhungert.</p> <p>Und was das vorgebliche "ins Lächerliche ziehen" betrifft, das wird der liebe TS schon aushalten, zumal ich absolut nichts erkennen kann, womit ich den Urheber persönlich hätte beleidigen oder ins Lächerliche hätte ziehen wollen.</p> <blockquote> <blockquote> <p>(scnr)</p> </blockquote> <p>Das hilft dann auch nicht mehr.</p> </blockquote> <p>Soll's ja auch nicht. Das war ja auch nicht als Abschwächung gedacht. In der Sache selbst bleib ich sicher dabei - man kann alles übertreiben. Ausser natürlich, man sieht die Entwicklung von Web-Applikationen als akademisches Angelegenheit, dann kann man natürlich Zeit in Probleme investieren, die es ohne die Applikation gar nie gegeben hätte.</p> <blockquote> <p>Oder kannst Du definitiv auf ein Speicherleck bei PHP in diesem Zusammenhang hinweisen?</p> </blockquote> <p>Sicher nicht, PHP ist für mich nur ein Werkzeug, das halt irgendwie funktionieren sollte, wie eine Schaufel. Wenn ich ein Loch grabe, dann analysier ich auch nicht den Bagger...</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784831#m1784831 Rolf B 2021-02-24T18:13:00Z 2021-02-24T18:13:00Z Aufteilung der Funktion, MVC <p>Hallo vapita,</p> <p>du baust da schon hübsch sortiert was zusammen. Was ich ändern würde:</p> <h3>getQuery</h3><p>dazu hatte ich schon mal was geschrieben. Diese Methode ist so, wie sie ist, Quatsch. Wenn Du schon Exceptions wirfst, dann lass sie auch fliegen und fang sie nicht gleich wieder ein. Was Du mit $queryException machst, ist mir schleierhaft: mit define festgelegte Konstanten tragen kein $, eine globale Variable müsste mit global deklariert werden, und statische Konstanten in der Klasse sollte ein Request:: oder self:: Präfix tragen. Soweit ich das sehe, läufst Du im Errorhandling auf eine undefinierte Variable. Das gleiche gilt für die Fehlerwerte aus User::validate.</p> <h3>register</h3><p>Was befindet sich, wenn Du $this->user->validate aufrufst, im user Property des UserControllers? Wird da von getUser was hineingelegt? Aber welcher - wenn Du registrierst, gibt es ja keinen angemeldeten User. Dies scheint mir falsch konstruiert. Entweder sollte validate eine statische Methode sein, die Du mit User::validate(...) aufrufst, oder Du änderst das Vorgehen so, dass Du einfach erstmal den User konstruierst und darauf dann validate als Instanzmethode rufst. Hier wäre übrigens eine Stelle, wo man durchaus try/catch verwenden kann.</p> <pre><code class="block language-php"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token variable">$userData</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token variable">$userRepository</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getEntityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">persist</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'302'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'user/login'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$validationException</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> this<span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token variable">$validationException</span><span class="token operator">-></span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Über Entitymanager und Repository wollte ich gerade auch schon anfangen, aber aber klugerweise mal gegoogelt. Du verwendest Symfony und Doctrine - das ist also so vorgegeben für Dich. Jetzt verstehe ich auch, warum Du fleißig set-Methoden verwendest. Das muss so, sonst bekommt Doctrine nicht mit, dass sich Propertywerte ändern.</p> <h3>class Password</h3><p>Das sieht nach einer statischen Klasse aus. Eigentlich brauchst Du davon keine Instanz. Mach die Methoden static und ruf dann bspw. <code>Password::hash(...)</code> auf.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784830#m1784830 Der Martin 2021-02-24T17:12:59Z 2021-02-24T17:12:59Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo,</p> <blockquote> <blockquote> <p>Das erinnert mich an die Bilder von CDs, die jemand zum Abheften gelocht hatte.</p> </blockquote> <p>Da waren die 3,5er Disketten praktischer, die waren schon im richtigen Abstand vorgelocht …</p> </blockquote> <p>stimmt, und die 5¼"-Disketten konnte man mit etwas Vorsicht auch so lochen, dass die eigentliche Disk in der Plastikhülle nicht beschädigt wurde.</p> <p>Live long and <s>pros</s> healthy,<br>  Martin</p> <div class="signature">-- <br> Lasst uns ins Horn brechen und aufstoßen. Höchste Zeit, auf den Weg zu machen.<br> (mit freundlichem Dank an <a href="https://forum.selfhtml.org/self/2021/feb/20/telefonbuch-ruckwartssuche/1784617#m1784617" rel="noopener noreferrer">Tabellenkalk</a> für die Ergänzung ) </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784838#m1784838 Robert B. 2021-02-24T19:55:59Z 2021-02-24T19:55:59Z Reihenfolge beim Überprüfen neuer Passwörter <p>Moin,</p> <p>und wenn es fürs Lochen nicht ganz reicht, gibt es immer noch CDs, DVDs und Blueray-Discs.</p> <p>Viele Grüße<br> Robert</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784839#m1784839 vapita 2021-02-24T20:02:39Z 2021-02-24T20:10:33Z Aufteilung der Funktion, MVC <p>Hallo Rolf,</p> <blockquote> <h3>register</h3><p>Was befindet sich, wenn Du $this->user->validate aufrufst, im user Property des UserControllers?</p> </blockquote> <p>Das ist die User-Klasse mit den Validierungen.</p> <p>Ich habe $this->user = new User(); im Abstrakten Controller verwendet von dem Jeder Controller erbt. Jedoch erscheint mir das inzwischen nicht mehr sinnvoll, da ich ja die User-Validierung gar nicht in jedem Controller benötige.</p> <blockquote> <pre><code class="block language-php"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token variable">$userData</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token variable">$userRepository</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getEntityManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">persist</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'302'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'user/login'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$validationException</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> this<span class="token operator">-></span><span class="token property">flash</span><span class="token operator">-></span><span class="token function">add</span><span class="token punctuation">(</span><span class="token variable">$validationException</span><span class="token operator">-></span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'danger'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> </blockquote> <p>Das ist ein guter Tipp. Danke dafür.</p> <blockquote> <p>Über Entitymanager und Repository wollte ich gerade auch schon anfangen, aber aber klugerweise mal gegoogelt. Du verwendest Symfony und Doctrine - das ist also so vorgegeben für Dich. Jetzt verstehe ich auch, warum Du fleißig set-Methoden verwendest. Das muss so, sonst bekommt Doctrine nicht mit, dass sich Propertywerte ändern.</p> </blockquote> <p>Das sieht tatsächlich so aus. Ist es aber gar nicht. Hinter der EntityManager Klasse befindet sich noch ein unaufgeräumtes Kinderzimmer. Ich habe mich allerdings von Doctrine inspirieren lassen. Allerdings nutze ich die Twig Engine für die View.</p> <pre><code class="block language-php"><span class="token comment"># EntityManager.php</span> <span class="token keyword">use</span> <span class="token package"><span class="token punctuation">\</span>ReflectionClass</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package"><span class="token punctuation">\</span>ReflectionProperty</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package"><span class="token punctuation">\</span>ReflectionException</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package"><span class="token punctuation">\</span>Exception</span><span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Btinet<span class="token punctuation">\</span>Ringhorn<span class="token punctuation">\</span>Logger</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name-definition class-name">EntityManager</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$db</span><span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token variable">$entity</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function-definition function">__construct</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Database</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">persist</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">,</span> <span class="token variable">$id</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword static-context">self</span><span class="token operator">::</span><span class="token function">generateReflectionClass</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$class_name</span> <span class="token operator">=</span> <span class="token function">strtolower</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">entity</span><span class="token operator">-></span><span class="token function">getShortName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">entity</span><span class="token operator">-></span><span class="token function">getProperties</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token variable">$property</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$property</span> <span class="token keyword">as</span> <span class="token variable">$key</span> <span class="token operator">=></span> <span class="token variable">$value</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$key</span> <span class="token operator">==</span> <span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$rp</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ReflectionProperty</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">,</span> <span class="token variable">$value</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$rp</span><span class="token operator">-></span><span class="token function">isInitialized</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$mvalue</span> <span class="token operator">=</span> <span class="token function">ucfirst</span><span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$method</span> <span class="token operator">=</span> <span class="token string double-quoted-string">"get<span class="token interpolation"><span class="token variable">$mvalue</span></span>"</span><span class="token punctuation">;</span> <span class="token variable">$data</span><span class="token punctuation">[</span><span class="token variable">$value</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$entity</span><span class="token operator">-></span><span class="token variable">$method</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token variable">$row</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"SELECT * FROM <span class="token interpolation"><span class="token variable">$class_name</span></span> WHERE id = :id"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$id</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$row</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token variable">$class_name</span><span class="token punctuation">,</span> <span class="token variable">$data</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$id</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token variable">$class_name</span><span class="token punctuation">,</span> <span class="token variable">$data</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">remove</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">,</span> <span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword static-context">self</span><span class="token operator">::</span><span class="token function">generateReflectionClass</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$class_name</span> <span class="token operator">=</span> <span class="token function">strtolower</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">entity</span><span class="token operator">-></span><span class="token function">getShortName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$row</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"SELECT * FROM <span class="token interpolation"><span class="token variable">$class_name</span></span> WHERE id = :id"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$id</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$row</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token variable">$class_name</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$id</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">truncate</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword static-context">self</span><span class="token operator">::</span><span class="token function">generateReflectionClass</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$class_name</span> <span class="token operator">=</span> <span class="token function">strtolower</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token property">entity</span><span class="token operator">-></span><span class="token function">getShortName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">truncate</span><span class="token punctuation">(</span><span class="token variable">$class_name</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">newMessage</span><span class="token punctuation">(</span><span class="token variable">$e</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">customErrorMsg</span><span class="token punctuation">(</span><span class="token variable">$e</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">protected</span> <span class="token keyword">function</span> <span class="token function-definition function">generateReflectionClass</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">entity</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ReflectionClass</span><span class="token punctuation">(</span><span class="token variable">$entity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">ReflectionException</span> <span class="token variable">$reflectionException</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">newMessage</span><span class="token punctuation">(</span><span class="token variable">$reflectionException</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name static-context">Logger</span><span class="token operator">::</span><span class="token function">customErrorMsg</span><span class="token punctuation">(</span><span class="token variable">$reflectionException</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Der Manager setzt im Prinzip für jede initialisierte Property der Entity-Klassen die Werte für die SQL-Abfragen. Daher die ganzen set-Methoden.</p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784849#m1784849 Rolf B 2021-02-25T10:24:58Z 2021-02-25T10:24:58Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo vapita,</p> <p>hash() - ok <br> verify() - ok </p> <p>Den Grund, warum deine Methoden Arrays verarbeiten sollen, habe ich jetzt endlich verstanden ‍♂️. Aber warum sie auch Strings können sollen, hm. <code>Password::verify</code> hat einen auf <code>array</code> getypten Parameter, da können die privaten Methoden nichts anderes bekommen. Du kannst in diesen privaten Helfern davon ausgehen, dass ein Array herein kommt und sie ebenfalls auf <code>array</code> typen.</p> <p>isString() - vom Algorithmus her nach wie vor nicht ok. Wenn Du in der Schleife einfach nur an $passwordIsString zuweist, ist das Ergebnis immer das vom letzten Schleifendurchlauf. Es gibt zwei richtige Techniken: (1) verwende eine UND Verknüpfung, (2) weise nur zu, wenn die Prüfung FALSE ergibt.</p> <p>Und der ?? Operator in der Schleife ist nach wie vor unnötig, is_string gibt niemals NULL zurück.</p> <p>Also, entweder (vom Prinzip her) so:</p> <pre><code class="block language-php"><span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$array</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>oder so</p> <pre><code class="block language-php"><span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$array</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$passwordIsString</span> <span class="token operator">=</span> <span class="token variable">$passwordIsString</span> <span class="token operator">&&</span> <span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Man muss das im zweiten Beispiel leider so umständlich schreiben. PHP kennt zwar kombinierte Zuweisungen bei Arithmetik (<code>+=</code>, <code>-=</code> etc), aber kein <code>&&=</code>.</p> <p>Wenn nach der Schleife - so wie bei Dir - nichts mehr passiert, kannst Du es auch vereinfachen, wobei die Päpste strukturierter Programmierung darüber die Stirn runzeln dürften. Ich nicht, ich mache sowas gern.</p> <pre><code class="block language-php"><span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$array</span> <span class="token keyword">as</span> <span class="token variable">$item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">is_string</span><span class="token punctuation">(</span><span class="token variable">$item</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> </code></pre> <p>Mit funktionalen Ansätzen wie <code>array_reduce</code> und Pfeilfunktionen (ab PHP 7.4) komme ich Dir jetzt besser nicht </p> <p>isEqual() - nicht prinzipiell falsch, aber hier ist nochmal das Konzept gefragt. Wenn isString ein beliebig langes Array verarbeiten kann, sollte das isEqual dann nicht auch tun? Die Methoden einer Klasse sollten eine logische Konsistenz aufweisen. Wenn Du beliebig viele PW verarbeiten können willst:</p> <pre><code class="block language-php"><span class="token keyword">function</span> <span class="token function-definition function">isEqual</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">count</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// 0 oder 1 PW übergeben</span> <span class="token variable">$comp</span> <span class="token operator">=</span> <span class="token variable">$password</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$password</span> <span class="token keyword">as</span> <span class="token variable">$pw</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$pw</span> <span class="token operator">!==</span> <span class="token variable">$comp</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Diese Methode ist zwar leicht ineffizient, weil sie den ersten Eintrag des Arrays mit sich selbst vergleicht, aber andernfalls könntest Du nicht foreach benutzen, es müsste eine <code>for ($i=1; $i<count($password); $i++)</code> Schleife sein. Das ist auch nicht besser.</p> <p>isComplex - ich finde die Anforderungen zu strikt. Normal ist es, drei von vier dieser Kategorien zu verlangen. Alle vier ist sehr streng, und vor allem ist der Zwang zu @#-_$%^&+=§!? zu streng. Ich möchte das Passwort "Lämmlein*17" verwenden! Vermutlich kann man meine folgenden Überlegungen heiß diskutieren; es ist nur meine eigene Meinung aus 36 Berufsjahren, die ich als Opfer der IT-Security verbracht habe, nicht als Täter.</p> <p>Auf Internationalisierungsprobleme will ich gar nicht erst eingehen (was macht ein Russe, der kyrillisch tippt? Was macht ein Chinese mit seinen Ideogrammen?). Um hier besser zu werden, müsste man mittels Unicode-Kategorie prüfen. \p{Lu} sind Großbuchstaben, \p{Ll} Kleinbuchstaben und \p{Nd} Ziffern. Und dann noch ein Zeichen, was in diesen Kategorien <strong>nicht</strong> ist. Dafür muss man, denke ich, vier mal matchen, und man darf nicht preg_match nehmen, sondern es muss <code>mb_ereg</code> sein (diese Funktion ist Unicode-fähig und kann mit UTF-8 codierten Strings umgehen). Nicht <code>mb_ereg_match</code>, die verankert die Prüfung am Beginn. Wir wollen aber nur die Existenz eines Zeichens testen.</p> <pre><code class="block language-php"><span class="token keyword">function</span> <span class="token function-definition function">isComplex</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$password</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">is_array</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_pop</span><span class="token punctuation">(</span><span class="token variable">$password</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token variable">$password</span><span class="token punctuation">;</span> <span class="token variable">$spaceCount</span> <span class="token operator">=</span> <span class="token function">mb_strlen</span><span class="token punctuation">(</span><span class="token variable">$p</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token function">mb_strlen</span><span class="token punctuation">(</span><span class="token function">mb_ereg_replace</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"\p{Zs}"</span><span class="token punctuation">,</span> <span class="token string double-quoted-string">""</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$hasUpper</span> <span class="token operator">=</span> <span class="token function">mb_ereg</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"\p{Lu}"</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$hasLower</span> <span class="token operator">=</span> <span class="token function">mb_ereg</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"\p{Ll}"</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$hasOther</span> <span class="token operator">=</span> <span class="token function">mb_ereg</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"\p{Lo}"</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$hasNumber</span> <span class="token operator">=</span> <span class="token function">mb_ereg</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"\p{Nd}"</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$hasOther</span> <span class="token operator">=</span> <span class="token function">mb_ereg</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"(?!(\p{Nd}|\p{Ll}|\p{Lu}|\p{Zs}))."</span><span class="token punctuation">,</span> <span class="token variable">$p</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Und jetzt braucht man eine Entscheidungsregeln. Ich würde beispielsweise ein Passwort akzeptieren, dass nur (kleinbuchstaben oder großbuchstaben) und space enthält, aber länger als 25 Zeichen ist (siehe <a href="https://xkcd.com/936/" rel="nofollow noopener noreferrer">"correct horse battery staple"</a>). Der Space-Anteil sollte aber unter - sagenwirmal - 15% liegen (das korrekte Pferd hat schon 10,7%!). Die $hasOther Kategorie trifft viele Fremdalphabete, z.B. finde ich bei Thai oder Arabisch <strong>nur</strong> \p{Lo } Zeichen. Diese <a href="https://de.wikipedia.org/wiki/Unicodeblock_Vereinheitlichte_CJK-Ideogramme" rel="nofollow noopener noreferrer">字亦属</a><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p> <p>Diese Regeln solltest Du jetzt für Dich formulieren, und dann der Reihe nach prüfen, ob sie erfüllt sind.</p> <p>Oder Du bleibst bei deiner Regex, wenn Dir das jetzt alles zu mystisch wird.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Das sollte "Buchstaben (gemeint sind die CJK-Ideogramme), auch, gehören dazu" bedeuten, wenn ich die Zeichenliste richtig deute . That's all <s>greek</s> chinese to me… <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784857#m1784857 Raketenlagermeister 2021-02-25T13:00:02Z 2021-02-25T13:00:02Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <p>Nur aus Neugier: warum nicht als *.phps?</p> </blockquote> <p>weil ich</p> <pre><code class="block language-bash"><span class="token keyword">for</span> <span class="token for-or-select variable">s</span> <span class="token keyword">in</span> *<span class="token punctuation">\</span>.php<span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token function">ln</span> <span class="token string">"<span class="token variable">${s}</span>"</span> <span class="token string">"<span class="token variable">${s}</span>.txt"</span><span class="token punctuation">;</span> <span class="token keyword">done</span> </code></pre> <p>getippt habe.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784861#m1784861 Raketenlagermeister 2021-02-25T13:30:32Z 2021-02-25T13:30:32Z Apropos Peter Pan <p><a href="/images/d708ff00-776b-11eb-addd-b42e9947ef30.jpg" rel="noopener noreferrer"><img src="/images/d708ff00-776b-11eb-addd-b42e9947ef30.jpg?size=medium" alt="Peter Pan ist tot..." title="Peter Pan ist tot..." loading="lazy"></a></p> <p>WK1, Oberitalien.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784862#m1784862 Peter Pan (no reg.) 2021-02-25T13:35:57Z 2021-02-25T13:35:57Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hi,</p> <p>manchmal ist keine Antwort auch ok. Oder sogar besser.</p> <div class="signature">-- <br> off: pp </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784863#m1784863 Raketenlagermeister 2021-02-25T13:36:14Z 2021-02-25T13:36:14Z Bevor gefragt wird <p>Ich darf das. Ich bin der Urheber des Fotos.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784875#m1784875 Matthias Apsel matthias.apsel@selfhtml.org https://brückentage.info 2021-02-25T15:19:31Z 2021-02-25T15:19:31Z Apropos Peter Pan <p>Hallo Raketenlagermeister,</p> <blockquote> <p><a href="/images/d708ff00-776b-11eb-addd-b42e9947ef30.jpg" rel="noopener noreferrer"><img src="/images/d708ff00-776b-11eb-addd-b42e9947ef30.jpg?size=medium" alt="Peter Pan ist tot..." title="Peter Pan ist tot..." loading="lazy"></a></p> <p>WK1, Oberitalien.</p> </blockquote> <p>Dobbiaco?</p> <p>Bis demnächst<br> Matthias</p> <div class="signature">-- <br> Du kannst das Projekt SELFHTML unterstützen,<br> indem du bei Amazon-Einkäufen <a href="https://smile.amazon.de/ch/314-570-45498" rel="nofollow noopener noreferrer">Amazon smile</a> (<a href="https://www.amazon.de/gp/help/customer/display.html?ie=UTF8&nodeId=202035970%5D" rel="nofollow noopener noreferrer">Was ist das?</a>) nutzt. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784864#m1784864 Raketenlagermeister 2021-02-25T13:48:53Z 2021-02-25T13:48:53Z Reihenfolge beim Überprüfen neuer Passwörter <p>Freilich hätte ich auch</p> <pre><code class="block language-bash"><span class="token keyword">for</span> <span class="token for-or-select variable">s</span> <span class="token keyword">in</span> *<span class="token punctuation">\</span>.php<span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token function">ln</span> <span class="token string">"<span class="token variable">${s}</span>"</span> <span class="token string">"<span class="token variable">${s}</span>s"</span><span class="token punctuation">;</span> <span class="token keyword">done</span> </code></pre> <p>tippen können.</p> <p>Aber ich bin mir nicht sicher was der Webserver (und dann der Browser von jeder{mann|frau|divers}, dann wömöglich das befasste OS ) damit das tun, was Du wohl im Auge hast.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784867#m1784867 Rolf B 2021-02-25T14:31:06Z 2021-02-25T14:31:34Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Raketenlagermeister,</p> <blockquote> <p>Aber ich bin mir nicht sicher was der Webserver (...) damit das tun, was Du wohl im Auge hast.</p> </blockquote> <p>Das solltest Du aber sein, wenn es dein eigener Webserver ist. Denn damit der PHPS Abruf funktioniert, musst Du dort einen CGI/FastCGI Handler für PHPS Files eingerichtet haben, der PHP mit der -s Option ausführt.</p> <p>Wobei es auch einen Trick mit einem Rewrite-Handler gibt, der auf ein Adapterscript umleitet, in dem highlight_file aufgerufen wird. Das spart das Kopieren von PHP nach PHPS, nur ist das auf einem öffentlich zugänglichen Server ein Einfallstor für Gift, Galle und Schabernack…</p> <p>Aber das hab ich gerade mal zum Spaß bei mir lokal gemacht, dolle Sache . Als alter Microsoftie natürlich <a href="https://docs.microsoft.com/en-us/iis/application-frameworks/running-php-applications-on-iis/enable-php-syntax-highlighting-on-iis-7-and-above" rel="nofollow noopener noreferrer">auf dem IIS</a>, aber das geht sicherlich auch im Indianerzelt.</p> <p>Jetzt such ich nur noch einen in PHP geschriebenen Highlighter für HTML, CSS und JS - das sucht sich im Netz so schlecht. Die wollen mir alle in JS geschriebene Highlighter für PHP andrehen, ich mag aber keinen Node dahinterklemmen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784869#m1784869 Auge 2021-02-25T14:38:28Z 2021-02-25T14:38:28Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo</p> <blockquote> <p>Jetzt such ich nur noch einen in PHP geschriebenen Highlighter für HTML, CSS und JS - das sucht sich im Netz so schlecht.</p> </blockquote> <p>Früher™️ hätte ich wohl <a href="https://github.com/GeSHi/geshi-1.0" rel="noopener noreferrer">GeShi</a> empfohlen, aber da dort seit über einem Jahr auch nichts mehr passiert <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>, fällt mir das schwer.</p> <blockquote> <p>Die wollen mir alle in JS geschriebene Highlighter für PHP andrehen, ich mag aber keinen Node dahinterklemmen.</p> </blockquote> <p><a href="https://highlightjs.org/" rel="nofollow noopener noreferrer">highlight.js läuft im Browser</a> und ist von seinem Lieferumfang her konfigurierbar.</p> <p>Tschö, Auge</p> <div class="signature">-- <br> Ein echtes Alchimistenlabor musste voll mit Glasgefäßen sein, die so aussahen, als wären sie beim öffentlichen Schluckaufwettbewerb der Glasbläsergilde entstanden.<br> <em>Hohle Köpfe</em> von Terry Pratchett </div> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>letzes Release: Oktober 2019, letzter Commit: Juni 2020 <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784876#m1784876 Henry 2021-02-25T15:31:22Z 2021-02-25T15:31:22Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Rolf,</p> <blockquote> <p>Jetzt such ich nur noch einen in PHP geschriebenen Highlighter für HTML, CSS und JS - das sucht sich im Netz so schlecht.</p> </blockquote> <p>Warum in PHP?</p> <blockquote> <p>Die wollen mir alle in JS geschriebene Highlighter für PHP andrehen, ich mag aber keinen Node dahinterklemmen.</p> </blockquote> <p>Kann ich verstehen, auch sonst so die üblichen Verdächtigen ,mit ihrem GitHub Gedönse usw.. Habe in den letzten Wochen aber ebenso verzweifelt gesucht und bin fündig gworden. Für mich der flexibelste und resourceschonende Highlighter, gleichzeitig auf Wunsch sogar Editor ist, Codemirror.</p> <p><a href="https://codemirror.net/" rel="nofollow noopener noreferrer">https://codemirror.net/</a></p> <p>Gruss<br> Henry</p> <div class="signature">-- <br> Meine Meinung zu DSGVO & Co:<br> „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“ </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784872#m1784872 Rolf B 2021-02-25T15:03:04Z 2021-02-25T15:03:04Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Auge,</p> <p>jaaaa, okeeeee - ich wollt's halt am Server tun, um nicht auf JS im Browser angewiesen zu sein.</p> <p>Aber ich schau es mir mal an.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784879#m1784879 Raktenlagermeister 2021-02-25T15:50:15Z 2021-02-25T15:50:15Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <blockquote> <p>Jetzt such ich nur noch einen in PHP geschriebenen Highlighter für HTML, CSS und JS - das sucht sich im Netz so schlecht.</p> </blockquote> <p>Früher™️ hätte ich wohl <a href="https://github.com/GeSHi/geshi-1.0" rel="noopener noreferrer">GeShi</a> empfohlen, aber da dort seit über einem Jahr auch nichts mehr passiert [^1], fällt mir das schwer.</p> </blockquote> <p>Jepp. Habe Geshi für mich selbst mehrfach umgeschrieben.</p> <p>Erst, damit das Zeug CSS-Klassen statt Farbangaben ausspuckt, zuletzt auf das es mit PHP8 läufe.</p> <p>Und ich verwende tunlichst einen eigenen Cache…</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784887#m1784887 vapita 2021-02-25T17:43:08Z 2021-02-25T17:43:08Z Highlight.js für PHP <blockquote> <p>Hallo Auge,</p> <p>jaaaa, okeeeee - ich wollt's halt am Server tun, um nicht auf JS im Browser angewiesen zu sein.</p> <p>Aber ich schau es mir mal an.</p> <p><em>Rolf</em></p> </blockquote> <p>Hallo Rolf,</p> <p>ich habe dies hier im Keller gefunden. Ein PHP Port von Highlight.js:</p> <p><a href="https://github.com/btinet/highlight.php" rel="noopener noreferrer">Highlight PHP</a></p> <p>Beste Grüße</p> <p>vapita</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784877#m1784877 Raketenlagermeister 2021-02-25T15:44:33Z 2021-02-25T15:44:33Z Apropos Peter Pan <blockquote> <p>Dobbiaco</p> </blockquote> <p>Pflaumenschnapsberg</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784878#m1784878 Matthias Apsel matthias.apsel@selfhtml.org https://brückentage.info 2021-02-25T15:48:15Z 2021-02-25T15:48:15Z Apropos Peter Pan <p>Hallo Raketenlagermeister,</p> <blockquote> <blockquote> <p>Dobbiaco</p> </blockquote> <p>Pflaumenschnapsberg</p> </blockquote> <p><em lang="it">Sacrario Militare di San Candido</em></p> <p>Bis demnächst<br> Matthias</p> <div class="signature">-- <br> Du kannst das Projekt SELFHTML unterstützen,<br> indem du bei Amazon-Einkäufen <a href="https://smile.amazon.de/ch/314-570-45498" rel="nofollow noopener noreferrer">Amazon smile</a> (<a href="https://www.amazon.de/gp/help/customer/display.html?ie=UTF8&nodeId=202035970%5D" rel="nofollow noopener noreferrer">Was ist das?</a>) nutzt. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784881#m1784881 Raketenlagermeister 2021-02-25T16:06:52Z 2021-02-25T16:06:52Z Apropos Peter Pan <blockquote> <blockquote> <blockquote> <p>Dobbiaco</p> </blockquote> <p>Pflaumenschnapsberg</p> </blockquote> <p><em lang="it">Sacrario Militare di San Candido</em></p> </blockquote> <p>Fast. <em lang="it">Monte Grappa</em> wäre superkorrekt gewesen.</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784880#m1784880 Matthias Apsel matthias.apsel@selfhtml.org https://brückentage.info 2021-02-25T15:55:21Z 2021-02-25T15:55:21Z Reihenfolge beim Überprüfen neuer Passwörter <p>Hallo Raktenlagermeister,</p> <blockquote> <p>Erst, damit das Zeug CSS-Klassen statt Farbangaben ausspuckt,</p> </blockquote> <p>HTML-Klassen </p> <p>Bis demnächst<br> Matthias</p> <div class="signature">-- <br> Du kannst das Projekt SELFHTML unterstützen,<br> indem du bei Amazon-Einkäufen <a href="https://smile.amazon.de/ch/314-570-45498" rel="nofollow noopener noreferrer">Amazon smile</a> (<a href="https://www.amazon.de/gp/help/customer/display.html?ie=UTF8&nodeId=202035970%5D" rel="nofollow noopener noreferrer">Was ist das?</a>) nutzt. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784884#m1784884 kai345 2021-02-25T16:17:01Z 2021-02-25T16:17:01Z Reihenfolge beim Überprüfen neuer Passwörter <blockquote> <p>Jepp. Habe Geshi für mich selbst mehrfach umgeschrieben.</p> <p>Erst, damit das Zeug CSS-Klassen statt Farbangaben ausspuckt, […]</p> </blockquote> <p>Wäre mir zu viel Aufwand. Mir hat <code>$geshi->enable_classes();</code> eigentlich immer gereicht, auch wenn die erzeugten Klassen-Namen nicht sehr schön sind.</p> <div class="signature">-- <br> Stur lächeln und winken, Männer! </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784882#m1784882 Raktenlagermeister 2021-02-25T16:10:05Z 2021-02-25T16:10:05Z Doch kein Pflaumenschnaps <blockquote> <blockquote> <blockquote> <blockquote> <p>Dobbiaco</p> </blockquote> <p>Pflaumenschnapsberg</p> </blockquote> <p><em lang="it">Sacrario Militare di San Candido</em></p> </blockquote> <p>Fast. <em lang="it">Monte Grappa</em> wäre superkorrekt gewesen.</p> </blockquote> <p>Ist halt nur kein Pflaumenschnaps, sondern ein Weinresteschnaps. Aber was geht mich Schnaps an?</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784883#m1784883 Matthias Apsel matthias.apsel@selfhtml.org https://brückentage.info 2021-02-25T16:16:28Z 2021-02-25T16:16:28Z Doch kein Pflaumenschnaps <p>Hallo Raktenlagermeister,</p> <p>ich meine, das wäre hier <a href="https://de.wikipedia.org/wiki/Innichen#/media/Datei:BeinhausInnichen.2008-06-28.png" rel="nofollow noopener noreferrer">https://de.wikipedia.org/wiki/Innichen#/media/Datei:BeinhausInnichen.2008-06-28.png</a>, aber am Monte Grappa war ich auch schon.</p> <p>Bis demnächst<br> Matthias</p> <div class="signature">-- <br> Du kannst das Projekt SELFHTML unterstützen,<br> indem du bei Amazon-Einkäufen <a href="https://smile.amazon.de/ch/314-570-45498" rel="nofollow noopener noreferrer">Amazon smile</a> (<a href="https://www.amazon.de/gp/help/customer/display.html?ie=UTF8&nodeId=202035970%5D" rel="nofollow noopener noreferrer">Was ist das?</a>) nutzt. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784885#m1784885 Raktenlagermeister 2021-02-25T17:07:12Z 2021-02-25T17:07:12Z Doch kein Pflaumenschnaps <p>Sieht nur ähnlich aus.</p> <p>Die Anlage auf dem Monte Grappa ist tatsächlich sehr ähnlich, aber um Klassen größer…</p> <p>Warum sich viele damit auskennen: Diese Kriegerfriedhöfe bieten den mit großen Fahrzeugen Reisenden von der EU und Deutschland finanzierte Toiletten, ruhige Parkplätze und (in Griechenland nicht zu empfehlen) Trinkasser...</p> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784886#m1784886 Matthias Apsel matthias.apsel@selfhtml.org https://brückentage.info 2021-02-25T17:21:10Z 2021-02-25T17:21:10Z Doch kein Pflaumenschnaps <p>Hallo Raktenlagermeister,</p> <blockquote> <p>Die Anlage auf dem Monte Grappa ist tatsächlich sehr ähnlich, aber um Klassen größer…</p> </blockquote> <p>In der Tat. <a href="https://de.wikipedia.org/wiki/Monte_Grappa#/media/Datei:MONTE_GRAPPA_(6899070536).jpg" rel="nofollow noopener noreferrer">https://de.wikipedia.org/wiki/Monte_Grappa#/media/Datei:MONTE_GRAPPA_(6899070536).jpg</a> Dort war ich, nach dem ich nun dieses Bild gesehen habe, tatsächlich noch nicht. Ich hatte einen großen Soldatenfriedhof mitten im Wald im Hinterkopf. Wo das aber nun genau war, kann ich grade nicht sagen.</p> <p>Bis demnächst<br> Matthias</p> <div class="signature">-- <br> Du kannst das Projekt SELFHTML unterstützen,<br> indem du bei Amazon-Einkäufen <a href="https://smile.amazon.de/ch/314-570-45498" rel="nofollow noopener noreferrer">Amazon smile</a> (<a href="https://www.amazon.de/gp/help/customer/display.html?ie=UTF8&nodeId=202035970%5D" rel="nofollow noopener noreferrer">Was ist das?</a>) nutzt. </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784888#m1784888 Auge 2021-02-25T20:20:54Z 2021-02-25T20:23:22Z Highlight.js für PHP <p>Hallo</p> <blockquote> <blockquote> <p>jaaaa, okeeeee - ich wollt's halt am Server tun, um nicht auf JS im Browser angewiesen zu sein.</p> </blockquote> <p>ich habe dies hier im Keller gefunden. Ein PHP Port von Highlight.js:</p> <p><a href="https://github.com/btinet/highlight.php" rel="noopener noreferrer">Highlight PHP</a></p> </blockquote> <p>Schade, da ist seit Mai 2019 auch nichts mehr geschehen. </p> <p><strong>edit</strong>: Hach Mist! Reingefallen!</p> <p>Das verlinkte Repo ist <a href="https://github.com/scrivo/highlight.php" rel="noopener noreferrer">ein Fork dieses Projekts</a> und fand der letzte Commit im Januar dieses Jahres statt.</p> <p>Tschö, Auge</p> <div class="signature">-- <br> Ein echtes Alchimistenlabor musste voll mit Glasgefäßen sein, die so aussahen, als wären sie beim öffentlichen Schluckaufwettbewerb der Glasbläsergilde entstanden.<br> <em>Hohle Köpfe</em> von Terry Pratchett </div> https://forum.selfhtml.org/self/2021/feb/23/reihenfolge-beim-uberprufen-neuer-passworter/1784892#m1784892 vapita 2021-02-26T12:07:09Z 2021-02-26T12:07:09Z Highlight.js für PHP <p>Hallo Auge,</p> <p>richtig. Dein Link stellt die bessere Wahl dar.</p> <p>Beste Grüße</p> <p>vapita</p>