‫-: In den letzten Videos haben
‫wir also einem Benutzer erlaubt, sein Passwort zurückzusetzen
‫und dann ein neues zu
‫erstellen, aber jetzt
‫möchten wir auch einem eingeloggten Benutzer ermöglichen, sein Passwort
‫einfach zu aktualisieren, ohne es vergessen
‫zu müssen, und so ohne diesen ganzen Reset-Prozess.
‫Also bauen wir das jetzt auf.
‫Und das
‫machen wir wie zuvor in unserem Authentifizierungs-Controller.
‫Also exportieren. Kennwort aktualisieren.
‫In Ordnung, und so, wie
‫immer, unsere drei Middleware-Parameter hier, und okay.
‫Denken Sie jetzt daran, dass diese Funktion zum Aktualisieren des
‫Passworts nur für eingeloggte Benutzer
‫gilt, aber wir müssen trotzdem sein aktuelles Passwort eingeben, um zu
‫bestätigen, dass der Benutzer
‫tatsächlich der ist, der er vorgibt zu sein.
‫Also nur als Sicherheitsmaßnahme, denn stellen
‫Sie sich vor, jemand würde Ihren Computer geöffnet vorfinden und
‫dann Passwörter auf den Websites ändern können, die Sie
‫gerade geöffnet haben,
‫ohne erneut nach einem Passwort gefragt zu werden.
‫Und das würde Sie im
‫Grunde von all Ihren bestehenden Anwendungen abmelden,
‫was natürlich eine schreckliche Erfahrung wäre.
‫Aus Sicherheitsgründen müssen wir daher immer
‫nach dem aktuellen Passwort fragen, bevor wir es aktualisieren.
‫Und vor diesem Hintergrund legen wir alle
‫Schritte fest, die wir unternehmen
‫müssen, um diese Funktionalität wie zuvor zu implementieren.
‫Als erstes müssen wir den Benutzer im Grunde
‫aus der Sammlung holen.
‫Als nächstes müssen wir überprüfen,
‫ob das veröffentlichte Passwort korrekt ist.
‫Rechts.
‫Dann drittens, also wenn das Passwort richtig ist,
‫dann aktualisieren Sie das Passwort.
‫Und schließlich müssen wir den Benutzer erneut anmelden,
‫also im Grunde das jsonwebtoken an den Benutzer zurücksenden, der
‫jetzt mit dem neuen, gerade aktualisierten Passwort angemeldet ist.
‫Okay, und das ist eigentlich alles sehr ähnlich zu dem,
‫was wir schon vorher
‫gemacht haben, und deshalb überlasse ich
‫dieses hier als Herausforderung für dich, okay?
‫Versuchen Sie also, dies selbst zu implementieren, und wenn Sie brauchen,
‫können Sie sich natürlich den Code ansehen, den wir
‫zuvor geschrieben haben, aber
‫versuchen Sie wirklich, den Code selbst zu schreiben,
‫ohne zu viel zu kopieren, okay ?
‫Sie können sich also den Rest des Codes ansehen,
‫um zu sehen, wie er funktioniert, aber dann kopieren Sie ihn nicht einfach, okay?
‫Denn dann wirst du nicht wirklich lernen, in Ordnung.
‫Also, pausiere das Video hier und wir sehen uns
‫gleich mit meiner Lösung.
‫Okay, ich hoffe, Sie haben es geschafft, dies zu
‫implementieren und zum Laufen zu bringen, so habe ich es gemacht.
‫Wir erstellen also wie immer eine neue Benutzervariable und warten dort
‫auf das Ergebnis von Benutzer. findById, und
‫woher kommt diese ID eigentlich?
‫Denken Sie noch einmal daran, dass dieses Update-Passwort nur für
‫authentifizierte, also für eingeloggte Benutzer gedacht ist, und
‫daher haben wir zu diesem Zeitpunkt bereits den
‫aktuellen Benutzer in unserem Anforderungsobjekt.
‫Okay, das kommt von der Protect Middleware.
‫Also, erf. Benutzer. id, und denken
‫Sie dann daran, dass wir explizit nach dem Passwort fragen müssen, okay?
‫Weil es standardmäßig nicht in der Ausgabe enthalten ist.
‫Also haben wir das im Schema definiert, erinnerst du dich?
‫Und wir brauchen dieses Passwort
‫tatsächlich, weil wir es jetzt mit dem
‫in der Datenbank gespeicherten
‫vergleichen wollen, und
‫dafür werden wir wie zuvor dieses Instanzobjekt verwenden, das
‫wir hier irgendwo haben.
‫Ja, also CorrectPassword, das in
‫allen Benutzerdokumenten verfügbar
‫ist, also zuerst das
‫Kandidatenpasswort und dann das eigentliche Benutzerpasswort, in Ordnung.
‫Oh, und jetzt bekomme
‫ich diesen Fehler, weil ich dies natürlich noch
‫nicht als asynchrone Funktion deklariert habe.
‫Also, async, und bevor wir es
‫vergessen, packen wir es auch hier in die catchAsync-Funktion ein.
‫Wie auch immer, wir
‫wollen hier im Grunde wie zuvor einen
‫Fehler erzeugen, wenn das aktuelle Passwort nicht korrekt ist,
‫und schreiben wir das in Code.
‫Also, wenn nicht Benutzer. correctPassword, und
‫dann merken Sie sich
‫das Kandidaten-Passwort, und damit eines
‫in einem Körper, in einer Eigenschaft, die wir passwordConfirm nennen.
‫Okay, und dann als zweites Argument das eigentliche Passwort, also
‫ein Benutzer. Passwort.
‫Und dann denken Sie daran, dass dies eine asynchrone Funktion ist
‫und wir sie daher auch hier abwarten müssen.
‫Gut, falls das Passwort nicht korrekt ist, erstellen
‫wir hier wie immer einen neuen Fehler.
‫Also, neuer AppError, und dieses Mal
‫sagen wir, dass Ihr aktuelles Passwort falsch ist,
‫und dann Statuscode 401 für nicht autorisiert.
‫Alles klar, großartig.
‫Wenn wir es nun im Code bis
‫zu diesem Punkt schaffen, also im Grunde, wenn das Passwort auch
‫korrekt ist, können wir das Passwort tatsächlich aktualisieren,
‫und wie machen wir das?
‫Nun, ganz einfach, das haben wir schon mal gemacht.
‫Wir sagen nur Benutzer. Passwort ist gleich req. Karosserie. Passwort, und
‫dann das gleiche natürlich für das Passwort bestätigen.
‫Okay, und die Validierung wird automatisch von dem Validator durchgeführt,
‫den wir im Schema angegeben haben, und das wird durchgeführt,
‫sobald wir es tatsächlich gespeichert haben.
‫Wir warten also auf den Benutzer. speichern, und deshalb
‫deaktivieren wir dieses Mal die Validierung
‫nicht, weil wir natürlich wollen, dass die
‫Validierung stattfindet. Wie ich bereits sagte, möchten
‫wir überprüfen, ob die Passwortbestätigung tatsächlich
‫mit dem Passwort übereinstimmt, oder?
‫Gut.
‫Und jetzt, um wirklich sicher zu gehen, dass Sie verstehen, warum wir so
‫etwas wie user nicht gemacht haben. findByIdAndUpdate.
‫Warum haben wir es nicht so gemacht?
‫Und ich weiß, dass ich schon oft darüber gesprochen habe,
‫aber ich möchte, dass Sie hundertprozentig verstehen, warum wir
‫dieses Update aus zwei Gründen nicht verwenden können,
‫also lassen Sie
‫mich noch einmal auf unser Modell zurückkommen.
‫Die erste
‫ist, dass diese Validierung hier nicht funktionieren wird, okay?
‫Und das liegt im Grunde daran. Das Passwort wird
‫beim Aktualisieren nicht definiert, also wenn wir find by ID und update
‫verwenden, weil Mongoose intern, hinter
‫den Kulissen, das aktuelle Objekt nicht wirklich im Speicher
‫behält, und daher wird dies hier nicht funktionieren.
‫Und wie gesagt, darüber habe ich schon
‫einmal gesprochen, also steht es hier auch tatsächlich aufgeschrieben, okay?
‫Aber es ist wirklich wichtig, daran zu denken, update
‫nicht für alles zu verwenden, was mit Passwörtern zu tun hat, in Ordnung?
‫Diese wird also
‫nicht funktionieren, und auch diese
‫beiden vorgespeicherten Middlewares werden nicht funktionieren.
‫Wenn wir also einfach update zum Aktualisieren
‫des Passworts verwenden, dann wäre dieses Passwort
‫nicht verschlüsselt, was
‫diese erste Middleware ist, und
‫dann wäre auch der PasswortChangedAt-Zeitstempel nicht gesetzt, okay?
‫Also, nichts davon würde
‫funktionieren, und deshalb müssen wir es wirklich so machen.
‫Stellen wir das einfach nochmal hier.
‫Und jetzt (murmelt) haben wir den Benutzer
‫eingeloggt und das Token an den Client zurückgeschickt.
‫Nun, das wäre tatsächlich das vierte Mal,
‫dass wir den gleichen Code erstellt
‫haben, also im Grunde dieses Stück
‫Code, und das ist jetzt sehr schnell in
‫seine eigene Funktion umgestaltet.
‫Nun, dieser Code ist tatsächlich nicht überall gleich.
‫Hier haben wir also den Statuscode 400
‫gesendet, und wir senden
‫den Benutzer nicht, aber hier oben im Signup-Handler haben wir tatsächlich
‫einen anderen Statuscode und wir haben
‫den Benutzer auch an den Client gesendet, okay?
‫Lassen Sie uns dies in unserer Funktion tatsächlich im Hinterkopf behalten.
‫Also, lassen Sie uns hier eine Funktion erstellen, Token erstellen und
‫senden, und dann sind die Argumente,
‫die wir hier brauchen, der Benutzer, weil
‫dort die ID gespeichert ist.
‫Dann wollen wir auch
‫den Statuscode, und natürlich müssen wir Zugriff auf das
‫Response-Objekt haben, um tatsächlich eine Response an
‫den Client zurücksenden zu können, okay?
‫Also brauchen wir jetzt im Grunde diesen Code.
‫Also kopieren wir es, fügen
‫es hier ein und ersetzen dann irrelevante Variablen.
‫Der Benutzer wird also einfach Benutzer genannt, also
‫genau so und hier dasselbe.
‫Also, kein
‫neuer Benutzer, und dann ersetzen wir das hier durch den
‫Statuscode, also den, der in unsere Funktion kommt, und
‫ich denke, das war es tatsächlich.
‫Also, lassen Sie uns jetzt fortfahren
‫und es ersetzen, also createSendToken, und hier heißt der Benutzer newUser,
‫der Statuscode ist
‫201 und dann natürlich das Antwortobjekt.
‫Okay, jetzt können wir diesen Code loswerden und
‫kopieren ihn einfach.
‫Okay, also beim Login haben wir natürlich auch einen Token
‫geschickt, aber diesmal heißt der User tatsächlich User und der
‫Statuscode ist 200.
‫Und jetzt kopieren wir diesen.
‫Also, der nächste sollte hier sein, und Passwort zurücksetzen, und
‫hier ist es
‫tatsächlich dasselbe, also der Name ist Benutzer und
‫Code 200, und jetzt ist es endlich auch hier dasselbe.
‫Damit ist unsere Passwortaktualisierungsfunktion abgeschlossen.
‫Damit dies nun funktioniert,
‫müssen wir die Route natürlich auch hier in unserem
‫User-Router implementieren.
‫Also Router. patch, und wir werden
‫einen Patch machen, weil wir uns tatsächlich ändern,
‫also das Benutzerdokument manipulieren, und dafür ist Patch da.
‫Und die Route heißt updateMyPassword.
‫Also, mein Passwort,
‫weil es für den aktuell angemeldeten Benutzer ist, und denken Sie
‫daran, dass dies nur für angemeldete Benutzer
‫funktioniert, und daher müssen wir authController verwenden. Protect, der dann auch
‫das User-Objekt
‫auf ein Request-Objekt legt, okay?
‫Also, schützen und dann das authController-Update-Passwort, das
‫wir gerade erstellt haben, in Ordnung.
‫Also, lassen Sie uns das jetzt tatsächlich testen, okay?
‫Also, kopieren wir diese Route hier, also
‫UpdateMyPassword, und jetzt müssen
‫wir diese drei Passwörter im Hauptteil senden, also ist
‫es im Grunde das
‫PasswortCurrent, und im Moment lasse ich sie leer,
‫ich möchte
‫einfach das Feld einfügen Namen hier vorerst.
‫Also, passwordCurrent, dann nur Passwort, was im Grunde
‫das neue
‫ist, und dann natürlich passwordConfirm.
‫Okay, und jetzt müssen wir uns tatsächlich als Benutzer
‫anmelden, denn denken Sie daran, dies
‫funktioniert nur, wenn der Benutzer bereits angemeldet ist.
‫Also lassen Sie es uns hier mit dem Administrator machen.
‫Und das hier ist, sollte immer noch das aktuelle Passwort
‫sein, und tatsächlich sind wir jetzt eingeloggt.
‫Und denken Sie daran, dass dieses
‫Token jetzt in der
‫JWT-Umgebungsvariablen gespeichert wird, und verwenden wir
‫es hier zur Authentifizierung genau wie zuvor.
‫Auf dieser Autorisierungsregisterkarte wählen wir also Bearer Token aus,
‫und dann wird diese JWT-Variable
‫automatisch vorab ausgefüllt.
‫In Ordnung, und daher wird dann
‫die Benutzer-ID eigentlich herkommen, erinnerst du dich?
‫Wie auch immer, lassen Sie uns jetzt das aktuelle Passwort angeben, also pass1234, und
‫dann sagen wir neues Passwort, okay?
‫Kopiere es und füge
‫es hier ein, aber eigentlich möchte ich
‫es noch einmal mit einem falschen Passwort-Bestätigen testen,
‫nur um zu sehen, ob unsere Validierung noch
‫funktioniert und jetzt ist die Route nicht definiert,
‫aber das liegt einfach daran, dass wir es verwenden hier das falsche Verb.
‫Natürlich muss es gepatcht werden.
‫Versuchen wir es noch einmal,
‫aber jetzt bekommen wir, dass Ihr aktuelles Passwort falsch ist, aber
‫eigentlich ist es das nicht, also ist es tatsächlich richtig.
‫Mit unserem Code muss also etwas nicht stimmen,
‫also versuchen wir es hier.
‫Und ja, hier liegt
‫eigentlich das Problem, denn wir wollen das Passwort natürlich nicht vergleichen
‫oder bestätigen, sondern mit dem aktuellen Passwort.
‫Okay, das ist nur ein dummer Fehler, in Ordnung, und
‫jetzt sollte es funktionieren.
‫Also wollen wir natürlich das aktuelle Passwort
‫mit dem aktuell
‫in der Datenbank gespeicherten vergleichen, in Ordnung.
‫Versuchen wir es
‫noch einmal, und das ist der Validierungsfehler, nach dem
‫wir gesucht haben. Die Passwörter sind
‫also nicht dieselben, weil sie es tatsächlich nicht sind.
‫Und jetzt, bevor wir das Passwort tatsächlich aktualisieren, werfen
‫wir einen Blick auf Compass hier.
‫Lassen Sie es uns hier schnell
‫aktualisieren, und im Moment ist dies das Passwort.
‫Hier endet also pW1i, okay?
‫Also aktualisieren wir jetzt das
‫Passwort und sehen, wie es danach aussehen wird, okay?
‫Also, jetzt sollte alles richtig sein.
‫Und tatsächlich bekommen wir unseren Erfolg und unser Zeichen, in Ordnung.
‫Also, lassen Sie uns das hier schnell bestätigen,
‫und tatsächlich sehen Sie, dass sich das Passwort
‫geändert hat und auch der aktuelle
‫Zeitstempel, also die Zeit, zu der ich dieses Video im Grunde aufnehme.
‫In Ordnung, und jetzt, genau wie zuvor, lassen
‫Sie uns diesen Test hier tatsächlich durchführen.
‫Also grundsätzlich das Token als Umgebungsvariable speichern.
‫Damit hier in Postman wirklich alles funktioniert.
‫Okay, speichern wir das tatsächlich,
‫aktualisieren wir das aktuelle Benutzerpasswort, um es wirklich eindeutig zu machen,
‫und ja, ich denke, das war es.
‫Ich denke, das ist alles, was wir tun müssen,
‫um das Passwort eines Benutzers zu aktualisieren.
‫Als nächstes werden wir dann die Aktualisierung anderer Benutzerdaten implementieren,
‫also Dinge wie E-Mail oder Passwörter.