‫-: In dieser Vorlesung werden wir dem
‫aktuell eingeloggten Benutzer erlauben, seine Benutzerdaten zu manipulieren.
‫Und jetzt verlassen wir durch die
‫Implementierung von Benutzeraktualisierungen wirklich den Bereich der
‫Authentifizierung und bewegen uns mehr in echte benutzerbezogene Dinge, okay?
‫Anstatt jetzt den Authentifizierungscontroller zu verwenden,
‫implementieren wir diese Aktualisierungsfunktion direkt
‫in ihrem userController.
‫Okay, wir
‫haben also eine Menge Handler, also
‫Routen, die hier nicht wirklich implementiert sind, okay?
‫Aber lassen wir sie vorerst
‫beiseite und erstellen unsere neue Handler-Funktion hier unten.
‫Und dieser wird updateMe heißen.
‫Und wieder heißt es updateMe, weil es zum Aktualisieren
‫des aktuell authentifizierten Benutzers dient.
‫Später werden wir dann auch
‫diese updateUser-Funktion hier implementieren, aber das ist dann
‫für wie ein Administrator, alle Benutzerdaten zu aktualisieren, während
‫der Benutzer selbst zumindest vorerst nur den Namen und die
‫E-Mail-Adresse aktualisieren kann.
‫Also, Anfrage, Antwort und weiter.
‫(Klackern der Tastatur) Und wir tun dies
‫tatsächlich, also aktualisieren die Benutzerdaten auf einem anderen
‫Weg als das Benutzerkennwort zu aktualisieren, denn normalerweise
‫wird dies in einer typischen Webanwendung
‫immer so gemacht.
‫Sie haben also normalerweise einen
‫Ort, an dem Sie Ihr Passwort
‫aktualisieren können, und dann einen anderen Ort, an dem
‫Sie Daten über den Benutzer oder das Konto selbst aktualisieren können.
‫Und hier folgen wir im Grunde einfach diesem Muster.
‫Beginnen wir also noch einmal damit, unsere Schritte zu skizzieren.
‫Und das erste, was wir hier
‫tun möchten, ist, im Grunde einen Fehler
‫zu erstellen, wenn der Benutzer versucht, das Passwort zu aktualisieren.
‫Erstellen Sie also einen Fehler, wenn der
‫Benutzer im Wesentlichen Passwortdaten postet.
‫Aber wenn nicht, müssen wir nur das Benutzerdokument aktualisieren.
‫So einfach genug, und fangen wir natürlich mit dem
‫ersten an.
‫Natürlich wird es eine
‫Stelle geben, an die wir die
‫Daten weitergeben werden, und wenn sich also in dieser Stelle Daten
‫zum Passwort befinden, oder eine Passwortbestätigung...
‫(Tasten klappern) Bestätigen.
‫Nun, in diesem Fall möchten wir sofort zurückkehren und
‫einen neuen Apperror erstellen.
‫Oh, und ich denke, wir haben es hier noch nicht implementiert
‫oder tatsächlich gefordert, also greifen
‫wir es einfach von hier an.
‫Also AppError...
‫Es ist
‫nicht hier, also der userController...
‫Also AppError, los gehts.
‫Also 'Diese Route ist nicht für Passwort-Updates bestimmt.
‫'Bitte verwenden Sie /updateMYPassword. ' Also im Grunde
‫die Route, die wir vorher angegeben haben.
‫Also updateMYPassword.
‫Und dann auch noch ein Code 400 für eine schlechte Anfrage.
‫Und das probieren wir gleich mal aus.
‫Und dafür nur zwei
‫Dinge, zuerst müssen wir eine Antwort
‫zurücksenden, also sagen wir res. status(200) für okay und dann json,
‫fügen Sie
‫den Status als erfolgreich hinzu.
‫Und später werden wir dann auch den aktualisierten Benutzer senden,
‫aber das belassen wir für später.
‫Das ist also die Antwort, und
‫jetzt müssen wir diese Route natürlich auch unserem Benutzer-Router hinzufügen.
‫Das ist natürlich ähnlich wie mein Passwort
‫zu aktualisieren, also Router, und natürlich ein Patch,
‫/updateMe,
‫andererseits ist es eine geschützte Route,
‫sodass nur der aktuell authentifizierte Benutzer die Daten des aktuellen
‫Benutzers aktualisieren kann.
‫Und so ist das alles natürlich sehr sicher,
‫da die ID des Benutzers, der aktualisiert werden soll, aus
‫der Anfrage stammt. user, der
‫hier von dieser Protect-Middleware gesetzt wurde, die wiederum die
‫Idee vom json-webtoken hatte, und da niemand die
‫ID in diesem json-webtoken ändern kann, ohne das
‫Geheimnis zu kennen, wissen wir,
‫dass die ID dann sicher ist deswegen.
‫Aus diesem Grund ist hier alles sicher.
‫Also userController. halte mich auf dem Laufenden.
‫Nun gut...
‫Lassen Sie uns das jetzt testen.
‫Fahren Sie fort und kopieren Sie dies erneut.
‫Und als erstes legen wir die Berechtigung fest.
‫Wieder vom Bearer Token und natürlich
‫mit dieser Umgebungsvariable.
‫Außerdem muss es sich um eine Patch-Anfrage handeln,
‫und wir müssen einen Hauptteil angeben.
‫Und ich möchte damit beginnen, es zu testen,
‫was natürlich diesen Fehler verursacht, und
‫lassen Sie uns ein Passwort und
‫dann einen Namen angeben.
‫Nehmen wir an, dies ist der Name, den wir aktualisieren möchten,
‫also speichern wir ihn hier.
‫Und tatsächlich befindet es sich natürlich im Benutzerordner.
‫Benutzerdaten.
‫Und tatsächlich erstellen wir hier einen neuen
‫Ordner und legen die Dinge, die sich auf die Authentifizierung beziehen,
‫in einen eigenen Ordner.
‫Also hier oben erstellen
‫wir einen neuen Ordner und nennen ihn Authentifizierung.
‫Das ist nicht richtig.
‫AH-DANN-TIKATION.
‫(kichert) Das war's also.
‫Das Passwort hängt also mit der
‫Authentifizierung zusammen, auch mit dem Zurücksetzen des Passworts, dem Vergessen des
‫Passworts, dem Anmelden und Abmelden.
‫Also, schließen wir diese beiden und
‫melden uns jetzt an, oder erstellen
‫wir einen neuen Benutzer.
‫Melden wir uns also
‫hier als normaler Benutzer an, damit wir diese beiden hier loswerden können.
‫Und jetzt rufe ich es einfach an, na ja, teste nochmal, in Ordnung?
‫Und werfen wir einen Blick darauf, welche Benutzer wir derzeit
‫in unserer Datenbank haben.
‫Also haben wir hallo und
‫admin, und verwenden wir jetzt test.
‫Und ich verwende immer wieder das gleiche Passwort, um
‫es wirklich einfach zu machen.
‫In Ordnung, wir müssen auch den Namen angeben, nennen wir
‫ihn hier einfach J.
‫Und jetzt bekommen wir tatsächlich unser Token, und
‫wir sind bereits angemeldet,
‫und wenn wir den Benutzer jetzt aktualisieren,
‫sollte das für diesen Benutzer sein, der gerade angemeldet war.
‫Ich versuche also nicht zu aktualisieren und
‫natürlich ist noch keine Aktualisierung implementiert und das wird also nicht funktionieren.
‫Alles, was ich sehen möchte, ist der Fehler,
‫der auftreten sollte, weil ich diese Kennworteigenschaft hier im Hauptteil angegeben habe.
‫Also probieren wir es aus.
‫Und hier bekommen wir diese Art seltsam aussehender Fehler, aber ich denke,
‫es liegt einfach daran, dass wir die Route hier
‫nicht wirklich aktualisiert haben. Denken
‫Sie also daran, dass ich gerade eine Route kopiert habe, also die URL,
‫und sie einfach hier eingefügt habe.
‫Aber natürlich muss es updateME sein.
‫Versuchen wir es also noch einmal.
‫Und so erhalten wir jetzt tatsächlich den von uns angegebenen Fehler.
‫"Diese Route ist nicht für Passwort-Updates gedacht.
‫"Bitte verwenden Sie /updateMyPassword. „So toll,
‫dieser Teil funktioniert und es
‫funktioniert auch, dass wir authentifiziert werden müssen.
‫Denn sagen wir, wir haben keine Authentifizierung, und
‫sagen wir das: No Auth.
‫Und so versuchen wir es jetzt noch einmal.
‫Und so heißt es tatsächlich: „Sie sind nicht eingeloggt!
‫"Bitte loggen Sie sich ein, um Zugang zu erhalten. "Also nur
‫um Ihnen zu beweisen, dass unsere Authentifizierung
‫auch hier ihren Job macht.
‫Aber natürlich wollen wir unseren Inhaber-Token,
‫und jetzt bekommen wir diesen anderen Fehler.
‫Großartig, also lassen Sie uns
‫jetzt den Rest der Funktionalität für den updateMe-Handler implementieren.
‫Aktualisieren Sie also das Benutzerdokument, und wir könnten versuchen, dies
‫mit dem Benutzer zu tun. sicher.
‫Also wie zuvor, im Grunde den Benutzer dazu bringen,
‫die Eigenschaften zu aktualisieren und dann am Ende
‫das Dokument zu speichern.
‫Das Problem dabei ist jedoch, dass einige
‫Felder erforderlich sind, die wir nicht aktualisieren,
‫und deshalb werden
‫wir einige Fehler machen.
‫Und um es Ihnen schnell zu demonstrieren, lassen
‫Sie mich das tatsächlich tun.
‫Okay, also sehr schnell, den Benutzer hierher zu bekommen.
‫Also findbyId, also anfordern. Benutzer, wie wir bereits wissen, . Ich würde.
‫Und dann sagen wir, Benutzer. name = 'Jonas' und dann auf
‫Benutzer warten. speichern.
‫Aber Sie sehen wieder, dass dies uns dann einen Fehler geben wird.
‫Aber vorerst deklarieren wir es natürlich
‫auch als asynchrone Funktion.
‫Und alles klar.
‫Lassen Sie es uns jetzt
‫testen, aber wir sollten jetzt mit einem Fehler rechnen.
‫Also lasst uns diesen natürlich
‫loswerden, und tatsächlich bekommen wir: "Bitte bestätigen Sie Ihr Passwort".
‫Das liegt daran, dass passwordConfirm ein Pflichtfeld ist, aber wir
‫haben es natürlich nicht angegeben.
‫Und so ist die sichere Methode in diesem Fall
‫nicht wirklich die richtige Option.
‫Stattdessen können wir
‫jetzt tatsächlich findById und update verwenden.
‫Das konnten wir also aus all den Gründen, die ich
‫Ihnen inzwischen mehrfach erläutert habe, nicht gebrauchen.
‫Da wir es aber jetzt nicht
‫mit Passwörtern, sondern nur mit diesen nicht sensiblen Daten wie Name oder
‫E-Mail zu tun haben, können wir jetzt findById und update verwenden.
‫Also, lass uns das loswerden.
‫Nennen wir es hier auch updateUser.
‫Und dann müssen wir hier nicht nur die ID übergeben,
‫sondern auch die Daten, die aktualisiert werden sollen,
‫und dann einige Optionen.
‫Also die Daten, nennen wir es hier jetzt x, und
‫ich sage Ihnen gleich
‫warum, und dann die Optionen, die wir übergeben möchten.
‫Und das ist genau wie zuvor,
‫die neue Option wird auf true gesetzt, sodass das
‫neue Objekt zurückgegeben wird,
‫also im Grunde das aktualisierte Objekt anstelle des alten.
‫Und die runValidators werden auch auf true gesetzt.
‫Denn tatsächlich wollen wir, dass die Modelle unser Dokument validieren.
‫Wenn wir beispielsweise eine ungültige E-Mail-Adresse eingeben, sollte diese vom
‫Validator abgefangen werden und einen Fehler zurückgeben.
‫Warum setze ich nun x hier ein und frage nicht einfach nach. Karosserie?
‫Nun, das liegt daran, dass wir eigentlich
‫nicht alles aktualisieren möchten, was sich im
‫Körper befindet, weil der Benutzer beispielsweise die Rolle in
‫den Körper einfügt.
‫Wir könnten Körper haben. rolle beispielsweise auf admin gesetzt,
‫so dass dann jeder Benutzer die
‫Rolle ändern kann, z. B. auf Administrator.
‫Und das darf natürlich nicht erlaubt sein.
‫Oder der Benutzer könnte auch seinen Reset-Token
‫ändern oder wenn dieser Reset-Token abläuft,
‫und all das sollte natürlich nicht erlaubt sein.
‫Daher wäre es natürlich ein großer
‫Fehler, so etwas zu tun.
‫Und deshalb müssen wir sicherstellen, dass
‫das Objekt, das wir hier
‫übergeben, also wieder das Objekt, das die zu
‫aktualisierenden Daten enthält,
‫nur Name und E-Mail enthält, da dies
‫im Moment die einzigen Felder sind, die
‫wir aktualisieren möchten .
‫Und im Grunde wollen wir den Body so
‫filtern, dass er am Ende nur Name und E-Mail enthält
‫und sonst nichts.
‫Wenn der Benutzer also versucht, die Rolle zu
‫ändern, wird das herausgefiltert,
‫damit es nie den Weg in unsere Datenbank findet.
‫Was wir also tun wollen, ist im Grunde eine Variable zu
‫erstellen und sagen
‫wir Filterkörper, und dann werden wir gleich eine Funktion erstellen, aber lass
‫uns sie hier schon verwenden, damit du
‫siehst, wie es funktionieren wird.
‫Und dann übergeben wir
‫hier die Daten, also das Objekt, das
‫wir filtern möchten, also req. body, weil dort alle Daten
‫sind, und dann übergeben wir ein paar Argumente.
‫Eines für jedes der Felder, die wir im Objekt
‫behalten möchten.
‫Wir möchten also das Feld namens name
‫und das Feld email beibehalten.
‫Und wieder, etwas später können wir hier weitere Felder hinzufügen,
‫zum Beispiel später können wir dem
‫Benutzer erlauben, ein Bild hochzuladen.
‫Und das müssen wir natürlich auch in
‫der Datenbank aktualisieren.
‫Aber im Moment wollen wir
‫nur den Namen und die E-Mail-Adresse im Körper behalten und den Rest herausfiltern.
‫Und hier verwenden wir jetzt natürlich
‫filterBody anstelle von x.
‫Was wir jetzt tun müssen, ist diese
‫Funktion zu implementieren, die sich um das Filtern des Objekts kümmert.
‫Also machen wir das hier.
‫FilterObj,
‫das ein Objekt und dann
‫die restlichen Parameter für alle zulässigen Felder aufnimmt.
‫Dadurch wird dann im Grunde
‫ein Array erstellt, das alle von uns übergebenen Argumente enthält.
‫Also im Grunde wurden die nach diesem ersten weitergegeben.
‫In diesem Fall handelt es sich also um ein Array, das Name und E-Mail enthält.
‫Was wir jetzt also tun
‫müssen, ist im Grunde das Objekt zu durchlaufen und für jedes Element zu prüfen,
‫ob es eines der erlaubten Felder ist,
‫und wenn ja, fügen Sie es einfach zu einem neuen Objekt hinzu,
‫das wir dann am Ende zurückgeben werden .
‫Und wahrscheinlich gibt es effizientere oder bessere Möglichkeiten, dies
‫zu implementieren, aber lass
‫es uns hier ganz schnell machen.
‫Also werden wir das
‫Objekt loopen, indem wir Object sagen. Schlüssel des Objekts, das wir übergeben.
‫Das ist also eine der einfachen Möglichkeiten, ein
‫Objekt in JavaScript zu durchlaufen.
‫Das hier gibt also im Grunde ein Array zurück,
‫das alle Schlüsselnamen enthält,
‫also die Feldnamen dieses Objekts, und
‫dann können wir sie durchlaufen.
‫Dann unsere Callback-Funktion.
‫Und für jedes Element werden wir dies tun.
‫Wenn also das zulässige Feldarray das
‫aktuelle Element enthält, also den aktuellen Feldnamen, möchten wir das
‫einem neuen Objekt hinzufügen.
‫Lassen Sie uns das hier schnell
‫erstellen, also const newObj, das vorerst leer ist,
‫und am Ende
‫ist es dasjenige, das wir zurückgeben werden.
‫Also neuObj.
‫Wenn das aktuelle Feld also eines der zulässigen
‫Felder ist, dann sollte newObj mit dem Feldnamen des aktuellen Felds gleich
‫dem sein, was sich im Objekt im aktuellen Element
‫befindet, also dem aktuellen Feldnamen.
‫Also nicht, wenn das etwas
‫verwirrend aussieht, das ist wieder nur
‫Standard-JavaScript, es hat nichts mit JS oder eXpress oder ähnlichem
‫zu tun.
‫Alles, was wir hier tun, ist also, im Grunde
‫alle Felder des Objekts zu durchlaufen und dann für
‫jedes Feld zu prüfen,
‫ob es eines der zulässigen Felder ist.
‫Und wenn ja, dann erstellen wir im neuen Objekt ein neues
‫Feld, natürlich mit
‫dem gleichen Namen, also immer noch name element, mit
‫genau dem gleichen Wert wie im Originalobjekt.
‫Und am Ende geben wir das natürlich zurück.
‫Und so sollte das hier jetzt alles funktionieren.
‫Dann müssen wir am Ende
‫nur noch diesen aktualisierten Benutzer an den Client senden.
‫Also, Benutzer.
‫Jetzt müssen wir den udatedUser dann natürlich hier ablegen,
‫erneut speichern, und jetzt sollte es funktionieren.
‫Sehen Sie wirklich, was wir hier gemacht haben. .
‫aktualisieren Sie den
‫Benutzer zuletzt, und zuvor haben wir unerwünschte
‫Feldnamen herausgefiltert, die nicht aktualisiert werden dürfen.
‫Also versuchen wir es jetzt.
‫Und dieser Benutzer hier ist ein normaler Benutzer, also haben wir ihn
‫gerade erstellt, erinnern Sie
‫sich mit dem Namen J.
‫Werfen wir also kurz einen Blick auf Compass.
‫Es ist also ein normaler Benutzer mit dem Namen J.
‫Also aktualisieren wir nun
‫den Namen und versuchen auch die Rolle zu
‫aktualisieren, was wiederum nicht erlaubt ist.
‫Aber um zu sehen, ob unser Code funktioniert, probieren wir es aus.
‫Der Name ist also bereits vorhanden, und nehmen wir an,
‫wir sind ein böswilliger
‫Benutzer, der versucht, unsere Rolle in Admin zu ändern.
‫Also, ich denke, alles ist richtig,
‫also lass uns das
‫jetzt senden, und tatsächlich ist hier unser aktualisiertes Objekt.
‫Wir bekommen also unseren neuen Namen, der Jonas Schmedtmann ist, und
‫dann die Rolle, die immer noch Benutzer ist.
‫Die Rolle wurde nicht auf Admin aktualisiert.
‫Perfekt. Genau das wollten wir.
‫Also, speichern Sie das und gehen wir zurück und tatsächlich
‫haben wir damit gerade dieses Video beendet.
‫Als nächstes implementieren wir dann eine Funktionalität zum
‫Löschen des aktuellen Benutzers.
‫Also haben wir an der Aktualisierung gearbeitet, als nächstes wollen wir es einem
‫Benutzer ermöglichen, sich grundsätzlich selbst zu löschen, wenn er nicht
‫mehr Teil unserer Anwendung sein möchte.