‫Kursleiter: In diesem und den
‫nächsten Videos implementieren wir
‫eine benutzerfreundliche Funktion zum Zurücksetzen von Passwörtern, die
‫in den meisten Webanwendungen Standard ist.
‫Und wahrscheinlich haben Sie das Zurücksetzen des Passworts
‫schon einmal auf einer Website verwendet und
‫normalerweise funktioniert es so.
‫Sie müssen nur Ihre E-Mail-Adresse angeben
‫und Sie erhalten dann eine E-Mail mit einem
‫Link, auf den Sie klicken können, und Sie gelangen
‫dann auf eine Seite, auf der Sie ein neues Passwort eingeben können.
‫Dies ist ein ganz normales Verfahren und so
‫werden wir es auch hier
‫in dieser Anwendung implementieren.
‫Grundsätzlich gibt es zwei Schritte.
‫Zum einen schickt der Benutzer nur mit
‫dieser E-Mail-Adresse eine Post-Anfrage an eine Route mit vergessenem Passwort.
‫Dadurch wird dann ein
‫Reset-Token erstellt und an die angegebene E-Mail-Adresse gesendet.
‫Nur ein einfaches, zufälliges Token, kein JSON-Web-Token.
‫Das ist hier ein Unterschied.
‫Im zweiten Teil, dem nächsten Video, sendet
‫der Benutzer dann dieses Token aus seiner E-Mail
‫zusammen mit einem neuen Passwort, um sein Passwort zu aktualisieren.
‫Grundsätzlich werden wir Exporte haben, die das Passwort vergessen haben, was der
‫erste Schritt ist.
‫Also Anfrage, Antwort und als nächstes und dann als zweiten
‫Schritt haben wir das Passwort zurückgesetzt.
‫Dann lassen Sie uns auch diese beiden Wege umsetzen.
‫Okay, und das steht natürlich in ihrem Benutzerrouter
‫oder ihrer Benutzerroutendatei.
‫Stellen wir sie auch gleich hier
‫oben und eigentlich kann ich diese Zeilen hier einfach duplizieren.
‫Also haben wir wieder Passwort vergessen,
‫das erst die
‫E-Mail-Adresse erhält und dann das Passwort zurücksetzt, das den
‫Token sowie das neue Passwort erhält.
‫Dies ist diejenige,
‫die wir in diesem Vortrag implementieren werden.
‫Lassen Sie uns wie zuvor unsere Schritte hier spezifizieren.
‫Rufen Sie also zuerst den Benutzer basierend
‫auf der geposteten E-Mail ab
‫und generieren Sie dann das zufällige Token.
‫Und dann im Grunde als E-Mail zurücksenden.
‫Dieses Zeug ist für uns derzeit ziemlich verbreitet.
‫Also user, also warten wir auf user dot find und jetzt ist es
‫find one, nicht nach ID
‫finden, weil wir die ID des Benutzers nicht kennen.
‫Und natürlich kennt der Benutzer auch seine eigene ID nicht
‫und so haben wir die E-Mail-Adresse angegeben.
‫Im Grunde ist es das einzige bekannte Datenelement.
‫Und das ist Stand auf Anfrage Punkt-Körper-Punkt-E-Mail-Adresse.
‫Und natürlich müssen wir jetzt
‫sagen, dass wir uns in einer asynchronen Funktion befinden und dann wie zuvor
‫in catch async einschließen.
‫Speichern Sie es und der Fehler sollte verschwunden sein.
‫Lassen Sie uns dann im nächsten Schritt
‫überprüfen, ob der Benutzer existiert.
‫Wenn also kein Benutzer vorhanden ist, dann kehren Sie natürlich mit einem
‫neuen Fehler zur nächsten Middleware zurück.
‫Ist kein Benutzer mit dieser E-Mail-Adresse.
‫Und dann können wir einen 404 setzen, was, wie Sie bereits
‫wissen, nicht gefunden bedeutet.
‫Als Nächstes generieren wir das zufällige Token und
‫dafür erstellen wir noch
‫einmal eine Instant-Methode für den Benutzer.
‫Denn auch das hat wirklich mit den
‫Benutzerdaten selbst zu tun.
‫Und wir werden wirklich ein bisschen Code
‫schreiben, und wenn es also nur eine Codezeile wäre,
‫dann könnten wir sie natürlich gleich hier einfügen.
‫Aber wir brauchen ein paar Zeilen
‫Code und daher ist es wieder ein bisschen
‫sauberer, ihn in seine eigene Funktion zu unterteilen.
‫Und das ist normalerweise mit Mungo am besten als Sofortmethode.
‫Also hier unten, lasst uns einfach hier am Ende bearbeiten.
‫Die Punktmethoden des Benutzerschemas erstellen also kein Token zum Zurücksetzen des Kennworts.
‫Ein ziemlich langer und aussagekräftiger Name.
‫Ich mache es gerne so,
‫damit ich genau weiß, womit ich es zu tun habe.
‫Das Token zum Zurücksetzen des Passworts sollte im Grunde eine
‫zufällige Zeichenfolge sein, muss aber
‫gleichzeitig nicht so kryptografisch stark sein wie der zuvor
‫erstellte Passwort-Hash.
‫Wir können einfach die sehr einfache, zufällige
‫Bytes-Funktion des integrierten Kryptomoduls verwenden.
‫Lassen Sie uns fortfahren und das tatsächlich hinzufügen.
‫Crypto erfordert und auch hier handelt es sich um ein integriertes Knotenmodul,
‫sodass Sie nichts installieren müssen.
‫Cool.
‫Nun, lassen Sie uns dann tatsächlich unseren Token generieren.
‫Und dafür verwenden wir Crypto Dot Random Bytes und dann
‫müssen wir hier grundsätzlich die Anzahl der
‫Zeichen angeben.
‫Und dann wandeln wir es am
‫Ende auch in einen hexadezimalen String um.
‫Zwei
‫Strings und dann können wir hier die Hex-Option angeben.
‫Wenn Sie sich jetzt
‫fragen, warum wir dieses Token
‫tatsächlich erstellen, habe ich es wohl noch nicht wirklich erklärt.
‫Im Grunde ist dieses Token das, was
‫wir an den Benutzer senden werden, und es ist wirklich wie ein
‫Reset-Passwort, das der Benutzer dann verwenden kann, um ein neues echtes Passwort zu erstellen.
‫Und natürlich hat nur der Benutzer Zugriff auf dieses Token.
‫Und so verhält es sich tatsächlich wie ein Passwort.
‫Da es sich im Wesentlichen nur um ein Passwort
‫handelt, bedeutet dies, dass, wenn ein Hacker Zugriff auf unsere Datenbank
‫erhält, der Hacker Zugriff auf das Konto erhält,
‫indem er ein neues Passwort setzt.
‫Wenn wir dieses Reset-Token jetzt einfach in
‫unserer Datenbank speichern würden, dann könnte ein Angreifer, wenn er Zugriff
‫auf die Datenbank erhält, diesen Token verwenden
‫und ein neues Passwort mit diesem Token erstellen, anstatt
‫dass Sie es tun.
‫Sie würden dann Ihr Konto effektiv kontrollieren, anstatt
‫dass Sie es tun.
‫Genau wie ein Passwort sollten wir
‫niemals ein einfaches Reset-Token in der Datenbank speichern.
‫Lassen Sie es uns
‫tatsächlich verschlüsseln, aber wie zuvor mit
‫dem Passwort braucht es keine so kryptografisch
‫starke Verschlüsselungsmethode.
‫Denn diese Reset-Token sind ein weitaus weniger
‫gefährlicher Angriffsvektor.
‫Auch hier verwenden wir nur das
‫eingebaute Kryptomodul.
‫Es funktioniert auf diese seltsam aussehende Art und Weise.
‫Wir sagen, dass Krypto dann Hash mit
‫dem sha 256-Algorithmus erstellt, dann müssen wir aktualisieren
‫und dann variabel
‫sagen, wo das Token gespeichert ist.
‫Welche Zeichenfolge wir grundsätzlich verschlüsseln möchten.
‫Und dann müssen wir Digest sagen und dann
‫wieder hexadezimal speichern.
‫Und wo werden wir diesen Reset-Token nun eigentlich speichern?
‫Nun, wir werden ein neues Feld in unserem Datenbankschema erstellen.
‫Denn natürlich wollen wir es in der Datenbank speichern,
‫um es dann mit dem
‫vom Benutzer bereitgestellten Token vergleichen zu können.
‫Machen wir das hier am Ende.
‫Token zum Zurücksetzen des Kennworts, das
‫ist die Zeichenfolge.
‫Und dann läuft auch das Zurücksetzen des Passworts ab.
‫Denn dieser Reset
‫läuft aus Sicherheitsgründen tatsächlich nach einer gewissen Zeit ab.
‫Sie haben nur 10 Minuten Zeit, um Ihr
‫Passwort tatsächlich zurückzusetzen.
‫Lassen Sie uns nun fortfahren und diese verwenden.
‫Dieses Dot-Passwort-Reset-Token ist dann dieser Verschlüsselung
‫gleich.
‫Als nächstes setzen wir das Passwort zurücksetzen abläuft ab
‫und setzen es auf den Datumspunkt jetzt und fügen dann
‫einfach ein paar Sekunden hinzu.
‫Wir wollen, dass es 10 Minuten
‫lang funktioniert, also sind das 10 und dann brauchen wir es in Millisekunden.
‫Mal 60 für Sekunden und dann mal 1000 für Millisekunden.
‫Und dann möchte ich auch das Klartext-Token zurückgeben, denn das
‫ist tatsächlich das, das wir per E-Mail
‫senden werden.
‫Zurücksetzen-Token zurückgeben.
‫Wir müssen den Reset-Token unverschlüsselt
‫per E-Mail versenden, da es sonst nicht
‫viel Sinn machen würde, ihn zu verschlüsseln.
‫Wenn das Token, das
‫sich in der Datenbank befand, genau das gleiche
‫wäre, mit dem wir das Passwort
‫tatsächlich ändern könnten, dann wäre das überhaupt keine Verschlüsselung.
‫Wir haben einen Token per E-Mail
‫gesendet und dann haben wir die verschlüsselte Version in unserer Datenbank.
‫Und dieser verschlüsselte ist dann im Grunde nutzlos,
‫um das Passwort zu ändern.
‫Es ist genau so,
‫als würden wir nur das verschlüsselte Passwort
‫selbst in der Datenbank speichern, genau wie hier oben,
‫also wo wir das Passwort mit bcrypt verschlüsselt haben.
‫Denken Sie daran, dass Sie sensible Daten immer
‫nur in verschlüsselter Form speichern und diese
‫dann mit der verschlüsselten Version vergleichen, die sich in
‫der Datenbank befindet.
‫Loggen Sie diese beiden einfach
‫in die Konsole ein, die unser Leben ein bisschen einfacher machen werden.
‫Sagen wir, Token zurücksetzen und ich melde
‫mich hier
‫als Objekt an, weil es mir dann tatsächlich den
‫Variablennamen zusammen mit seinem Wert mitteilt.
‫Und dann das gleiche mit diesem Punkt-Passwort-Reset-Token.
‫Dieser funktioniert nicht wirklich mit dem
‫Schreiben von Objekten, dieser neue ES6-Weg und
‫belassen wir es dabei.
‫Wie auch immer, lass uns
‫einfach hierher zurückkommen und dann diese Funktion verwenden.
‫Denken Sie also daran, wie wir das Reset-Token zurückgegeben haben,
‫und speichern wir es hier.
‫Der Reset-Token ist also gleich dem Benutzerpunktsatz und ich bin mir des
‫Namens nicht mehr sicher.
‫Erstellen Sie ein Token zum Zurücksetzen des Kennworts, das
‫ist also ein langer.
‫Alles klar und so ist das
‫erledigt, aber eigentlich haben wir nur die
‫Daten hier geändert.
‫Wenn wir dieses Punkt-Passwort zum Beispiel auf diesen
‫Wert setzen, haben wir das Dokument
‫tatsächlich nicht aktualisiert.
‫Wir haben es nicht gespeichert.
‫Wir modifizieren es eigentlich
‫nur, aber jetzt müssen wir es speichern.
‫Nehmen wir an, Benutzer warten auf Punktspeicherung.
‫Aber beobachten Sie, was passiert, wenn wir dies jetzt verwenden.
‫Nehmen wir einfach dieses hier.
‫Dies ist die Route, die wir zuvor gefunden haben.
‫Und jetzt bekommen wir diese Route noch nicht definiert.
‫Mal sehen, warum das so ist.
‫In der Benutzerroute haben wir hier eindeutig die gleiche URL, aber
‫ich sehe, dass wir tatsächlich eine Postanfrage stellen müssen.
‫Alles klar, okay, aber jetzt erhalten wir eine Fehlermeldung, die besagt,
‫dass Sie bitte E-Mail und Passwort angeben.
‫Und das meinte ich, als ich sagte, pass
‫auf, was passiert, wenn du das versuchst.
‫Dies geschieht, weil wir versuchen, ein Dokument zu speichern,
‫aber nicht alle obligatorischen Daten angeben, also die Felder,
‫die wir als erforderlich markiert haben.
‫Lass uns das schnell beheben.
‫Alles, was wir tun müssen, ist, eine spezielle
‫Option an diese Benutzerpunktspeichermethode zu übergeben.
‫Wir
‫sagen validieren, bevor das Speichern
‫auf false gesetzt wird.
‫Dadurch werden alle Validierer, die wir in unserem
‫Schema angegeben haben, deaktiviert.
‫Es sind diese kleinen Dinge, die Sie wissen
‫müssen, die den Unterschied ausmachen.
‫Jetzt wusste ich auch nicht, dass es das
‫gibt, weil niemand wirklich alles weiß.
‫Es ist unmöglich.
‫Eine Bibliothek wie Mongoose ist einfach viel zu
‫groß, um alles zu wissen.
‫Ich habe die Mongoose-Dokumentation gelesen
‫und dort diese äußerst hilfreiche Option gefunden.
‫All dies nur, um noch einmal zu
‫sagen, dass niemand alles
‫weiß, und daher ist es wirklich
‫eine gute Angewohnheit,
‫bei Problemen einen Blick in die
‫Dokumentation der Bibliothek zu werfen, die Sie verwenden.
‫Schauen wir uns das jetzt an.
‫Und wir bekommen hier immer noch den gleichen Fehler, aber
‫ich sehe hier unten,
‫dass er tatsächlich von der Login-Funktion kommt.
‫Schauen wir uns an, was hier vor sich geht.
‫Werfen wir auch einen Blick auf die Routen.
‫Ah, okay, hier ist das Problem.
‫Wir versuchen jetzt, den
‫Login-Handler aufzurufen, was natürlich keinen Sinn macht.
‫Hier ist es Passwort vergessen.
‫Hier ist es das Passwort zurücksetzen.
‫Der Fehler, den wir zuvor bekamen, lag also nicht
‫an der Validierung.
‫Senden wir dies noch einmal und
‫jetzt erhalten wir die Fehlermeldung, dass es
‫keinen Benutzer mit
‫dieser E-Mail-Adresse gibt und das liegt daran, dass wir
‫im Textkörper keine E-Mail-Adresse angegeben haben.
‫Wir haben das
‫getestet und jetzt ist es an der Zeit,
‫es mit einer Benutzer-E-Mail zu testen.
‫Gut.
‫Und jetzt sollte es
‫eigentlich nichts tun, weil wir keine Antwort zurücksenden.
‫Lassen Sie uns das
‫einfach abbrechen, denn alles, was mich
‫wirklich interessiert hat, ist, diese Token hier zu sehen und
‫dann auch einen Blick auf das Benutzerobjekt zu werfen.
‫Dies hier ist das ursprüngliche Reset-Token, also sehen Sie,
‫dass es ein zufälliger hexadezimaler String ist und dann
‫haben wir den verschlüsselten hier drin.
‫Diese Erinnerung ist diejenige, die nicht in der Datenbank enthalten
‫sein sollte und auf a901 endet.
‫Schauen wir uns das an.
‫Und tatsächlich, hier
‫ist es, Passwort-Reset-Token mit der Endung a901.
‫Und auch das Datum, das tatsächlich in 10 Minuten liegt.
‫Jetzt wissen Sie, zu welcher Zeit ich dieses Video aufnehme.
‫Wie auch immer, aber das hat gut funktioniert.
‫Dies ist also der erste
‫Teil der Erstellung dieser Funktion zum Zurücksetzen des Kennworts.
‫Im nächsten Video werden wir
‫diesen Token dann hier per E-Mail an den Benutzer senden und haben
‫so eigentlich ein separates Video vorbereitet, nur um
‫zu lernen, wie man tatsächlich E-Mails mit Knoten an
‫js sendet.
‫Das macht sehr viel
‫Spaß, also warten Sie nicht, um sofort dorthin zu ziehen.