Beiträge von cottton

    JTW ist sehr schönes Thema.

    Aber man muss es verstehen.


    Erstmal Link, zu dem Repo, welches ich empfehlen würde (und was auch wirklich "simple" ist =))

    https://github.com/firebase/php-jwt/


    Und Website https://jwt.io/, bei der Ich damals angefangen habe (Click auf "Learn more about JWT").


    In kurz und einfach (versucht) :

    - Json Web Token (JWT) werden vom Server z.B. nach erfolgreichem Login erstellt.

    - JWT sind (vom LoginServer) signiert (wenn man die Payload ändert, dann passt die Signatur nicht mehr).

    - der Server alleine kann die JWT signieren (mit private key).

    - jeder, der den JWT nun bekommt, kann sicher sein, dass die Daten darin nicht verändert wurden (weil signiert).

    - Die Signatur wird per public key geprüft.

    - Ein JWT sollte eine Verfallszeit haben.

    - Der Empfänger eines JWT muss diesen validieren (Signatur, noch valide, schon valide (ja, geht auch), ect).

    - Wer den JWT hat, hat die Berechtigung, bis dieser Abläuft.


    Wichtig: ein JWT sollte niemals sensible Daten beinhalten.

    Man liest ab und zu von verschlüsselten Daten im JWT, aber das ist mMn Mist. Da gehört nichts sensibles rein.


    Wo nutze ich JWT: Mirco Services z.B.

    Ein Auth login server, und viele unabhängige Services.

    Der User meldet sich an (Login Website mit call auf Auth Server) und bekommt einen JWT.

    Mit dem Token kann er nun zu jedem Micro Service. Und die wissen, dass er User das darf, was da drin steht (roles, groups, ...).


    ---

    Spannendes Thema, eigtl. gar nicht so schwierig, aber leider zu viel, um es hier alles runter zu schreiben.

    Daher hier einfach mal paar Links zu Kommentaren, die ich schon mal geschrieben habe (warum auch noch mal schreiben :D )


    JWT Client Bsp (und Erklärung, warum man die Daten darin nicht wiederverwenden sollte)

    https://github.com/firebase/ph…83#issuecomment-447845729


    Client-Server Bsp (und mehr).

    https://github.com/firebase/ph…19#issuecomment-525464922


    Mehrere JWT pro Benutzer?
    https://github.com/firebase/ph…31#issuecomment-433397553



    Viel Spass (das Thema macht auch Spass =) )

    Naja, ich würde in dem Fall auch nur das Array mit Gross- und Kleinbuchstaben füllen.

    Die Zeile $plainTextArray = str_split(strtolower($plainText));musst Du dann natürlich ändern, damit nicht alles auf Kleinbuchstaben gezwungen wird.

    Also strtolowerweg.


    Jetzt fehlen Dir ja dann auch noch andere Zeichen, Wie z.B. der Punkt, Komma, ... .

    Musst Du dann eben noch in das $alphabet array packen.


    BTW, was ich schon eher hätte erwähnen können: range()

    https://www.php.net/manual/de/function.range.php

    Siehe comment: https://www.php.net/manual/de/function.range.php#114493

    Code
    1. echo implode("",range("q","9 "));
    2. // prints qponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:987654

    Sieht interessant aus. Evtl kannst Du damit ein array mit Sonderzeichen erstellen.

    Ich empfehle sowas immer ohne HTML zu schreiben.

    Schreib Funktionen, oder Objekte, aber keine Loops mit HTML :)


    $alphabetkannst Du schon mal generieren.

    So in etwa (ungetested)

    PHP
    1. $alphabet = [];
    2. // Note: start with $i = 1 for 1-26 array offsets.
    3. for ($i = 1, $char = 'a'; $i <= 26; $i++) {
    4. $alphabet[$i] = $char;
    5. // Note: PHP gets the next char in alphabet on ++.
    6. $char++;
    7. }

    Und schon diese kleine Sache packst Du einfach schon mal weg in eine Funktion (z.B: generateAlphabetArray()).


    Als nächstes willst Du ja en- und de-coden.

    Also wird es sicher eine soUndSoEncode und soUndSoDecode Funktion geben.


    Diese beiden werden dann sicherlich gemeinsamen Code nutzen (können).

    Also packst Du diesen Code, wenn auch nur kleine Loops ect, in eine Funktion,

    die beide dann nutzen können.


    Oft schreib ich mir erstmal runter, wie ich das Ganze dann eigentlich aufrufen will,

    ohne zu wissen, was mich erwaret.

    In etwa (als Objekt (OOP)):

    Code
    1. // clear text example input
    2. $text = 'foo bar baz';
    3. // encode
    4. $caesar = new Caesar();
    5. $encryptedText = $caesar->encrypt($text); 
    6. // decode
    7. $clearText = $caesar->decrypt($encryptedText);

    So wüsste ich schon mal, was ich für (public) Funktionen haben wöllte.

    Dir selbst oder jemand, der es später nutzen würde, ist es dann relativ egal, was da drin passiert.

    Hauptsache der Call ist "angenehm".


    Wenn Du das dann als Webseite anzeigen willst, dann ist der Einbau ja recht einfach.

    Es ist aber schön getrennt - Funktion (Caesar) und Controller (Input|output (HTML, ....)).

    createFromFormat brauchst Du nicht, wenn es das datetime format aus der db ist.

    2021-05-01 12:00:00 = Y-m-d H:i:s

    und damit kommt PHP \DateTime klar.


    BTW; ich würde keine deutschen (var, function, db.column, ...) namen vergeben. Engl. is the way to go.
    Was, wenn Du mal hilfe auf z.B. stackoverflow oder anderen engl. sprachigen Seiten suchst? Dann versteht keiner den Code.

    Bissl spät, aber ...

    Jain.
    Muss bissl ausholen:

    Ich hab hier im Forum bei NULL angefangen.

    So um die 3 Jahre selbstständig PHP, MySQL, HTML, CSS, JS gelernt und ein eigenes Projekt gestartet (furchtbarer Code, aber viel dabei gelernt).

    Bei einer Firma angefragt, und bekam als Antwort: "Naja, OOP muss schon sein".

    Also ~1 Jahr OOP (objektorientierte Programmierung) gelernt.

    Neues, privates Projekt angefangen, um aktiv OOP einzusetzen.

    Wollte dann nen Zettel haben, um was vorzeigen zu können. Hab das bei ILS gemacht.


    Zum Fernstudium:
    Es wird wurde (vor 5-6 Jahren) Grundwissen vermittelt, dabei aber alter Code verwendet. Also z.B. mysql_functions statt mysqli_ oder PDO.

    BTW: nutzt PDO. Ich sag es immer wieder - es ist einfacher :)

    Die Tests waren langweilig - ich hab bei den Testbögen neben die Fragen geschrieben, dass hier und da SQL-Injections möglich wären usw.

    Das war so mein "Spass" bei der Sache - Fehler finden :x

    Naja, jedenfalls hatte ich dann einen Zettel, der aussagte, dass ich einen Onlinekurs abgeschlossen hatte.

    Ich hab dann weiter selbständig gelernt. War ja mein "Hobby", hat ja Spass gemacht.


    Ende vom Lied:

    Hilft der Zettel bei der Job suche? Kann sein. Aber am Ende zählt, was Du auf Fragen im Gespräch antworten kannst. Eigene online Projekte helfen natürlich auch.

    Ist es das Geld wert? Nein. Hab es vom Amt bezahlt bekommen. Aber selbst hätte ich es nicht bezahlt, für das, was man dafür bekommt.


    wie hoch ist der Lerneffekt vorausgesetzt


    Ich bekam Einführung von ganz am Anfang.
    Als xampp auf Windows installieren, "Hello World" im Browser ansehen, usw.

    Also kannst Du theoretisch ohne Vorwissen da rein gehen.

    Aber das Grundwissen - also was ist PHP, xamp, SQL, ... und wie spielt das alles zusammen - das kann und sollte man sich im Netz zusammen suchen.

    Z.B. hier: https://www.php-kurs.com/ (die PHP website dieses Forums)


    ---

    Um meine Geschichte zum Ende zu bringen:

    Ich wollte einen Job. Ich hab sogar ein locales Bewerbungstraining über das Amt mitgemacht.

    Die fragten mich, was ich hier (beim Training) will. Aber ich meinte nur, ich mach jetzt alles mit, was kommt.

    Am Ende des Tranings sollten wir uns 3 mögliche Praktikumsplätze suchen. Also Telefon in die Hand und los.

    Hatte 2, brauchte noch eines. Bei der dritten dachte ich "da kommste niemals rein, bei dem, was die schon gemacht haben".

    Und ZACK - Rückruf, Einladung zum Gespräch, Praktikum. Später dann direkt Festeinstellung.


    Und jetzt sitz ich hier, immernoch bei der gleichen Firma mit dem besten Chef der Welt :D

    und schreibe im Forum, in dem ich bei NULL angefangen hab, wäred der Arbeitszeit :x (welche aber dynamisch geregelt ist)


    Was will ich damit sagen: nimm alles mit, wenn es Dich nichts kostet, oder Geld keine Rolle spielt.

    Es braucht manchmal nur einen kleinen Zufall.

    Hätte ich dieses blöde Bewerbungstraining nicht gemacht, dann hätte ich diese Nummer nie angerufen.


    ---

    BTW: im Job lernst Du sowieso erst Dinge, die Dir keiner vorher beibringen kann|will.

    Schon alleine die eingesetzten Tools in der Softwareumgebung (dev) ändern sich über die Jahre, und von Firma zu Firma.

    Aber das ist kein Problem, sondern Entwicklung.

    Neues Projekt, oder Problem? Suche im Netz nach Lösung, Testen, Syntax ect lernen, Einsetzen.

    Als Entwickler lernst Du Dir selbst zu helfen. Vor dem Job noch immer im Job.


    Viel Glück.

    Kann nicht genau folgen.

    Zitat

    00:00 – 00:30 123

    Soll das angeben, wie viele User zu der Zeit angemeldet waren?

    Also 123 User in der halben Stunde?

    ---

    Du kannst GROUP BY nutzen. Zwar nicht mit halben Stunden (evtl mit nem "Trick"),

    aber ganz einfach über das Format:

    SQL
    1. GROUP BY DATE_FORMAT(`created_at`, '%Y-%m-%d %H')


    Example:

    SQL
    1. -- SET @date_format := '%Y-%m-%d'; -- Get grouped counts by hour.
    2. SET @date_format := '%Y-%m-%d %H'; -- Get grouped counts by hour.
    3. -- SET @date_format := '%Y-%m-%d %H:%i'; -- Get grouped counts by min.
    4. SELECT
    5. -- select the datetime by format
    6. DATE_FORMAT(`created_at`, @date_format) AS `created_at`,
    7. -- count the amount for that formatted datetime group
    8. COUNT(`user_id`) AS `count`
    9. FROM `user_login_log`
    10. GROUP BY DATE_FORMAT(`created_at`, @date_format);


    Test: http://sqlfiddle.com/#!9/aac84a/4

    Nein, "sollte" ist auf jeden Fall falsch und die Benennung nach Einzahl oder Mehrzahl entweder

    a) eine Glaubensfrage, oder

    b) ein firmeninterner Regelungsgegenstand , oder

    c) eine Geschmacksfrage.

    Ja klar, kann man sich streiten, muss man aber nicht.

    Das gibts im Netz genug.

    Bei mir z. B. werden Tabellen grundsaetzlich nach der Mehrzahl benannt, sofern dies moeglich ist. Die Begründung ist für mich auch logisch: Eine Tabelle, die viele XYZ verwalten soll, heisst dann eben xyzs (Mehrzahl) und nicht xyz (Einzahl). So kann man auch leicht zwischen einer Gruppe - z. B. Array $xyzs - und einem einzelnen Objekt - z. B. String $xyz - unterscheiden.

    Naja, das machst Du so lange, wie Du darfst. Also bis Dir dein Chef, oder Kunde was anderes sagt.


    Ich werd mich hier bestimmt nicht deswegen streiten :)

    Aber Dein Argument, dass es immer mehrere (rows) in einer Tabelle gibt, ist mMn keins. Alle Tabellen haben mehrere (rows). Und jetzt kannst Du das wieder gegen mich verwenden :D


    Dein Argument, dass mann zwischen einer Gruppe und einem Object unterscheiden kann, ist auch komisch (nur meine Meinung).

    Denn Das entscheidet doch dann der Code - also die Variablenbenennung.


    BTW: Code und Objects -

    wenn Du mit Models zu tun hast, dann wird es schnell seltsam:

    manche Models sind clever geschrieben, und erwarten, dass der Tabellenname strtolower(classname) heißt.

    Also Class UserLogin {} dann als user_login.

    Die musst Du dann immer explizit angeben.


    Du musst das Naming dann auch durch alle Ebenen durchziehen (oder ständig ändern, aber dann ist user mal user und auf einmal users oO?).

    Bsp:


    Auch ja - zwecks "user_login" - Thema Detailtabellen (oder halt Tabellen in Bezug auf andere):

    Code
    1. Meiner Meinung nach "positiv" Bsp:
    2. tbl user
    3. tbl user_login
    4. tbl user_login_attempt
    5. Meiner Meinung nach "negativ" Bsp:
    6. tbl users
    7. tbl users_log_ins
    8. tbl users_log_ins_attempts

    Ich will Dich nicht unbedingt Überzeugen. Aber ich finde, das sind schon gute Argumente =)

    Hat sich erledigt.

    Ok.


    vs_rooms

    Warum? Ich meine, warum kann man denn nicht einfach richtige Namen vergeben :)


    BTW: Mehrzahl ist ungünstig.

    Beispiel:

    SQL
    1. SELECT *
    2. FROM rooms
    3. JOIN floors on rooms.id = floors.rooms_id
    4. WHERE rooms.name = '...'
    5. ;

    Liest sich falsch, oder?

    Eine Tabelle sollte in der Einzahl benannt werden:

    SQL
    1. SELECT *
    2. FROM room
    3. JOIN floor on room.id = floor.room_id
    4. WHERE room.name = '...'
    5. ;

    Also zB "user" statt "users", "car" statt "cars", ... .


    Bei Spalten ist das was anderes.

    In deinem Beispiel hast Du seats. Ich gehe davon aus, dass hier die Anzahl stehen wird. Oder doch nur, ob es Sitze gibt? :D

    Würde eher seat_count empfehlen.

    Du siehst sofort, worum es geht.



    Und ... rooms.room - was ist das? :D

    Code
    1. [
    2. 'id' => 1,
    3. 'room' => '', // ?
    4. 'name' => 'Living Room',
    5. 'seats' => 'Yes', // :D
    6. ]


    :)

    Es ist ja offensichtlich, dass mit $x++ irgendetwas mit dieser Variable passiert. Da hätte man mit einem simplen


    Code
    echo $x;

    in der Schleife die Sache heraus finden können.

    Dann hätte er gewusst, dass sich die Zahl erhöht.

    Aber warum?

    Ich finde es besser, wenn man wei, wie etwas funktioniert. (In dem Fall ++$i, $i++)

    Aber wie gesagt - der ein Link zur offiziellen docu reciht da ja.

    Bitte Grundlagen lernen, denn hier hat niemand Lust dir die Doku "vorzulesen"

    Naja, ich erinnere mich, als ich angefangen hab.

    Wie sucht man denn als Anfänger dannach?

    Du kennst die Begriffe und die (für inzwischen uns logische) Web-Suche nicht.


    Ich weiß noch, wie ich nach "!" (not) suchen wollte :D

    Dann lieber gleich im Forum fragen :)


    EDIT: aber klar, ein Link zur PHP Beschreibung raicht dann als Antwort.

    Manmal machen Fehler aber keinen Sinn. Als ob 1 + 1 nicht mehr 2 ist.

    Dann ist es wirklich besser Pause oder Feierabend zu machen.


    Manchmal hift es auch schon im Forum eine Frage zu stellen.

    Schon beim Schreiben und Überlegen, wie man das Problem erklärt, fällt einem manchmal der Fehler auf :)


    dsaZeus Warum erstellst Du denn für jeden Benutzer eine eigene Datei (1.php, 2.php, ...)?

    Nur als Hinweis:

    Column als TIMESTAMP.

    see DATE, DATETIME oder TIMESTAMP?


    Die database timezone beachten.

    see mysql timezone ändern

    sehr ausführlich (muss man nicht alles wissen): https://stackoverflow.com/a/19075291/3411766


    Format immer: Y-m-d H:i:s (Bsp: 2020-05-18 03:14:59)


    PHP Datetime:

    $datetime = new \Datetime('2020-05-18 03:14:59', new \DateTimeZone('UTC'));


    PHP relative datetime: https://www.php.net/manual/de/datetime.formats.relative.php

    $datetime = new \Datetime('now', new \DateTimeZone('UTC'));

    $datetime = new \Datetime('this day noon', new \DateTimeZone('UTC'));

    $datetime = new \Datetime('first day of this month', new \DateTimeZone('UTC'));


    PHP modify:

    $datetime->modify('+1 day');


    Wenn Du die timezone in der db in UTC hast, kannst Du die dann per PHP in zB "Europe/Berlin" ändern

    PHP datetime timezone ändern: https://www.php.net/manual/de/datetime.settimezone.php


    oder per MySQL direkt in der query:

    MySQL: SELECT id, name, ... , CONVERT_TZ(my_datetime_column,'UTC','Europe/Berlin') FROM .... WHERE ...;

    Also sollte ich lieber immer htmlspecialchars benutzen?

    Immer dann, wenn Du etwas im Browser ausgibst.

    Selbst, wenn die Daten aus Deiner eigenen db, config, file, ... kommt.

    Wenn Du ein script in CLI (command line interface aka console) ausgibts, dann nicht, denn in der CLI with kein Javascript ausgeführt.


    Selbst ausprobieren macht Spass und man lern es besser: spiel einfach bisschen mit (zB) den username rum. Lass htmlspecialchars weg, und nutze irgendwelche Zeichen, die Dir einfallen. zB <, >, ", ', ....

    Schon ein username >hans< würde HTML "brechen".

    Verstehe das Problem nicht (bin gerade erst aufgewacht)

    aber bitte alle Werte mit htmlspecialchars maskieren.

    Bsp:

    Statt <?php echo $value['username'] ?>

    Bitte <?php echo htmlspecialchars($value['username']) ?>


    Warum: XSS (einfach mal im Netz suchen).

    Kannst Du selbst testen. Speichere mal einen username mit <script>alert(1)</script>Hans

    und lass Dir den User ausgeben.

    Ich fang jetzt nicht wieder mit Prepared Statements an. Das solltest Du nun kennen.

    Aber

    SELECT * FROM login WHERE username = '$username'

    Wenn im Moment, und|order in der Zukunft ein Fehler passiert,

    bei dem der username nicht (mehr) unique ist,

    dann kannst Du mehr als 1 user laden.


    Der code lässt dann auch noch zu, dass Du solange läufst, bis Du den letzten möglichen user eingeloggt hast.


    Pseudo code Vorschlag:

    Code
    1. result = SELECT * FROM login WHERE username = :username LIMIT 1;
    2. if result.count === 1
    3. row = result->fetchOne() // you expect one, so get one
    4. if password_verify(password, row.password)
    5. // all fine
    6. elseif result.count > 1
    7. // error handling for unexpected multiple users on same username
    8. else
    9. // error handling for user not found by username

    Vieleicht sollte man solche Antworten das ( ich falsch liege ) dann anders Formulieren weil falsch scheint meine ausage ja nicht gewesen zu sein.

    Ja, ich geb zu, dass war wohl too much von mir, sorry.

    Werde das in dem Post editieren|markieren|notieren.


    timtim

    Ich hätte mir gedacht dass ich Password_verify() im Anschluss an die SQL-Abfrage (hier Zeile-Nr. 20) schreiben müsste?

    "WHERE username=? AND password=?"

    ^ das funktioniert nicht.


    Du bekommst das plain text (klartext) Passwort.

    Du hast (in Deiner db) den hash des Passwortes.


    Du lädsts den User bei username oder email.

    Findest Du ihn, dann nimmst Du den zugehörigen hash und nutzt password_verify() um den das Passwort mit dem Hash zu vergleichen.