‫Sprecher: Bisher haben wir in
‫unserer Authentifizierungsimplementierung Benutzer mit einem korrekten Passwort angemeldet.
‫Im Grunde haben wir also diesen ersten Schritt des
‫Authentifizierungsworkflows abgeschlossen, bei dem
‫ein JSON-Webtoken erstellt und an den
‫Client zurückgesendet wird, wenn der Benutzer eine
‫korrekte E-Mail und ein korrektes Passwort angibt.
‫Als nächstes werden wir also tatsächlich geschützte Routen implementieren.
‫Also im Grunde die Verwendung des erstellten
‫JSON-Webtokens, um angemeldeten Benutzern Zugriff auf geschützte Routen zu geben.
‫Und dies ist der zweite Schritt der Authentifizierung.
‫Lassen Sie uns nun diese Funktionalität implementieren.
‫Nehmen wir an, wir wollten
‫die getAllTours-Route schützen.
‫Also grundsätzlich nur eingeloggten Benutzern erlauben,
‫auf eine Liste aller unserer Touren zuzugreifen.
‫Und was bedeutet, dass vor dem
‫Ausführen des Get-All-Tours-Handlers ein Blick
‫darauf geworfen wird.
‫Okay, bevor wir dieses Handle hier ausführen, müssen
‫wir also eine Überprüfung durchführen, um
‫zu überprüfen, ob der
‫Benutzer tatsächlich angemeldet ist oder nicht, oder?
‫Der beste Weg, dies
‫zu tun, ist, wie Sie
‫wahrscheinlich bereits wissen, die Verwendung einer Middleware-Funktion, in Ordnung?
‫Um Routen zu schützen,
‫werden wir in diesem Video eine
‫Middleware-Funktion erstellen, die vor jedem dieser Handler ausgeführt wird, okay.
‫Also eine Funktion, die genau hier
‫sitzt, bevor diese Funktion hier ausgeführt werden kann.
‫Und diese Middleware gibt dann entweder einen
‫Fehler zurück, wenn der Benutzer nicht
‫authentifiziert ist, also wenn
‫er nicht eingeloggt ist, oder
‫sie ruft die nächste Middleware auf, in diesem Fall der getAllTours-Handler, richtig?
‫Und das schützt diese Route
‫effektiv vor unbefugtem Zugriff.
‫Lassen Sie uns also schnell diese
‫Middleware-Funktion erstellen und sie
‫dann hier platzieren,
‫um zu veranschaulichen, was ich gerade gesagt habe.
‫Okay, also hier in unserem Auth-Controller werden wir
‫wieder eine neue Middleware-Funktion erstellen
‫und sie heißt Protect.
‫In
‫Ordnung, und genau wie zuvor werde
‫ich catchAsync verwenden, da alle diese
‫Funktionen tatsächlich asynchrone Funktionen sind.
‫Okay, und dann hier natürlich unsere Middleware-Funktion und
‫vorerst lasst uns hier ganz einfach als nächstes
‫aufrufen, nur damit wir hier tatsächlich irgendeinen
‫Körper in dieser Middleware-Funktion
‫haben und dann gehen wir zurück zu
‫unseren Tourrouten und schützen dann diese Route, okay ?
‫Zuerst muss ich dieses Authentifizierungs-Controller-Modul
‫tatsächlich benötigen.
‫Also
‫const und dann verlangen, dass
‫es in Controllern ist,
‫und dann authController, okay.
‫Also lass es uns
‫jetzt direkt hier in der getAllTours-Route einstecken.
‫Okay.
‫Also authController. schützen.
‫Okay.
‫Und so wird diese Middleware-Funktion im Moment zuerst und
‫wieder ausgeführt, wenn der Benutzer nicht authentifiziert ist, wird ein
‫Fehler auftreten.
‫Und natürlich dann die nächste Middleware,
‫also diejenige, die
‫eigentlich alle Touren bekommt und versendet, wird dann nicht ausgeführt.
‫Okay.
‫Auch hier wird der Zugriff auf diese
‫Ressource hier effektiv vor nicht eingeloggten Benutzern geschützt.
‫In Ordnung, also lass uns hierher zurückkehren.
‫Nicht die
‫Benutzerrouten, sondern der Authentifizierungscontroller.
‫Alles klar, und nun zur Implementierung
‫dieser Protect-Middleware.
‫Was genau müssen wir tun?
‫Nun, beginnen wir damit, dass wir hier ein paar Schritte ausführen.
‫Alles klar, und eigentlich müssen wir diese Funktion zuerst
‫als Async markieren, sonst würden wir den catchAsync
‫nicht wirklich brauchen, oder?
‫Und Sie werden gleich sehen, warum dies eine Async-Funktion
‫sein muss, in Ordnung?
‫Aber jetzt lassen Sie uns die Schritte erläutern,
‫die wir unternehmen müssen, um diese Middleware zum Schutz zu implementieren.
‫Genau wie zuvor werde
‫ich diese Schritte hier als Kommentare einfügen.
‫Zuerst müssen wir das Token tatsächlich erhalten.
‫Und überprüfen
‫Sie, ob es im Grunde genommen da
‫ist, also überprüfen Sie, ob es existiert.
‫Als nächstes müssen wir das Token validieren.
‫Und das ist im Grunde der superwichtige
‫Schritt, über den wir zuvor gesprochen haben, bei dem der JWT-Algorithmus überprüft, ob
‫die Signatur gültig ist oder
‫nicht.
‫Also, wenn das Token gültig ist oder nicht, okay?
‫Also nennen wir das hier eigentlich Verifizierung.
‫Ich denke, so haben wir es auf der Folie genannt,
‫auf der wir zuvor darüber gesprochen haben.
‫Und wenn Sie sich nicht wirklich erinnern, wie das funktioniert
‫hat, können Sie jederzeit
‫zurückgehen und sich den Vortrag noch einmal ansehen, in Ordnung?
‫Als nächstes müssen wir also, wenn die Überprüfung tatsächlich erfolgreich war,
‫auch überprüfen, ob der Benutzer, der versucht, auf
‫die Route zuzugreifen, noch existiert, okay?
‫Überprüfen Sie also, ob der Benutzer noch vorhanden ist, und ich
‫werde mehr darüber sprechen, warum
‫jeder dieser Schritte erforderlich ist, sobald wir mit der Implementierung beginnen, in Ordnung?
‫Im Moment macht das für Sie vielleicht nicht so viel
‫Sinn, aber ich werde noch einmal über jeden Halt sprechen, sobald wir dort sind.
‫Gut?
‫Und schließlich müssen wir auch
‫überprüfen,
‫ob der Benutzer das
‫Passwort geändert hat, nachdem
‫das JWT ausgestellt wurde, okay?
‫Nun, sagen wir hier einfach
‫Token, wir haben es überall sonst Token genannt, okay?
‫Und nur wenn es bei keinem
‫dieser Schritte hier Probleme
‫gab, wird natürlich der nächste aufgerufen, der dann Zugriff
‫auf die von uns geschützte Route erhält.
‫In unserem aktuellen Beispiel also wieder dieser getAllTours-Handler.
‫Richtig?
‫Okay, aber gehen wir
‫zurück und beginnen mit der Umsetzung unseres allerersten Schrittes hier.
‫Also im Grunde genommen das
‫Token holen und dann prüfen, ob es tatsächlich existiert.
‫Es ist also eine gängige Praxis, ein Token mit einem http-Header mit
‫der Anfrage zu senden, okay?
‫Schauen wir uns also an, wie wir Header in Postman setzen können,
‫um ihn zusammen mit der Anfrage
‫zu senden, und dann auch, wie wir
‫in Express auf diese Header zugreifen können.
‫Und das machen wir zuerst.
‫Also hier in apt. js Ich denke, wir haben hier
‫diese nette Middleware, also melden wir uns hier tatsächlich
‫bei der Konsolenanforderung an. Header, Okay, wir
‫haben vorher über http-Header gesprochen, und
‫so können wir in Express auf sie zugreifen.
‫Okay, also im Wesentlichen zu den Anforderungsheadern, also
‫denen, die ein Client zusammen mit seiner Anforderung senden kann.
‫Okay, und hier in Postman kommen wir nun tatsächlich
‫zu der Route, die wir eigentlich schützen wollen.
‫Und dann hier einen Header setzen.
‫Und lass uns einfach
‫einen Test machen und ihn auf jonas setzen, okay?
‫Jetzt schicke ich das
‫einfach und hier in Express, schauen wir uns das an.
‫Und so erhalten wir hier tatsächlich ein Objekt mit allen Headern,
‫die Teil der Anfrage sind.
‫Also das alles hier.
‫Und Sie sehen, dass es eine Reihe von
‫Headern gibt, die Postman tatsächlich automatisch zusammen mit
‫der Anfrage sendet, zum Beispiel, dass der User-Agent Postman ist und
‫auch der Host sendet, und einige
‫andere, über die wir später sprechen werden,
‫wie akzeptieren zum Beispiel.
‫Was hier zählt, ist eigentlich der Header, den
‫wir selbst gesetzt haben.
‫Okay, der Testheader wurde auf jonas gesetzt, den wir gerade
‫in unserer Anfrage gesendet haben.
‫Um nun ein JSON-Webtoken als Header zu senden, gibt
‫es dafür tatsächlich einen Standard.
‫Also lasst uns hierher zurückkehren, das alles loswerden.
‫Und so ist der Standard zum Senden eines Tokens, dass wir
‫immer einen Header namens Authorization verwenden sollten.
‫Okay?
‫Also einfach so und
‫dann sollte der Wert dieses Headers immer mit
‫Bearer beginnen, okay?
‫Denn im Grunde tragen wir, wir haben, wir besitzen diesen Token und dann
‫hier den Wert des Tokens.
‫Also genau wie diese zufällige Zeichenfolge, die wir zuvor bekommen haben.
‫Belassen wir es also einfach hier als Beispiel und schicken
‫wir das jetzt.
‫Und dann sollten wir es tatsächlich hier bekommen.
‫Okay.
‫Jetzt wandelt Express dann automatisch alle Header-Namen in
‫Kleinbuchstaben um, wie Sie hier sehen
‫können, aber unser Header-Wert hier ist natürlich immer noch derselbe.
‫Okay, und im Grunde ist dieser Teil des
‫Header-Werts unser Token.
‫Und so sollten wir jetzt
‫dieses Token aus dem Header lesen.
‫Gut?
‫Wenn also tatsächlich
‫req. Überschriften. Berechtigung, okay, und
‫wenn es
‫im Grunde mit diesem Trägerstring hier beginnt, okay, also
‫req. Überschriften. Autorisierung und jetzt
‫ist dies ein String
‫und damit können wirstartsWith verwenden,
‫okay, das ist also nur normales JavaScript wieder
‫okay.
‫Das sind also die Bedingungen, unter denen wir eigentlich
‫einen Token speichern wollen, okay?
‫Also noch einmal, falls der
‫Header existiert und sein Wert mit Bearer beginnt, okay.
‫Dann wollen wir in diesem Fall sagen, dass das Token gleich
‫req ist. Überschriften. Autorisierung und
‫wie bekommen wir nun diesen zweiten Teil
‫des Strings eigentlich?
‫Nun, im Grunde teilen wir den String
‫durch dieses Leerzeichen auf, okay, was dann
‫ein Array mit diesem
‫Bearer und
‫mit diesem Token erstellt, und dann
‫nehmen wir den Teil des
‫Arrays, den wir wollen.
‫Teilen Sie also mit Leerzeichen auf, und
‫dann wollen wir von diesem Array das zweite Element.
‫Gut?
‫Jetzt können wir eine Variable nicht wirklich innerhalb eines
‫if-Blocks definieren,
‫weil const, und let,
‫also die neuen ES6-Variablen-Deklaratoren tatsächlich blockbereichsbezogen sind,
‫und alles, was
‫wir hier in diesem Block definieren, wird dann
‫außerhalb davon nicht verfügbar sein.
‫Okay, und das machen wir draußen.
‫Und diesen Wert dann einfach dem Token neu zuweisen.
‫Okay.
‫Und jetzt loggen wir das Token in die Konsole ein,
‫um zu sehen, ob es funktioniert.
‫Okay, und tatsächlich holen wir uns hier
‫ein echtes Token.
‫Also der, mit dem wir uns gerade eingeloggt haben.
‫Und dann stell das hier rein, in Ordnung.
‫Also
‫schick es, und ah!
‫Auf geht's.
‫Hier haben wir also unsere JSON-Webtoken-Daten, die wir gerade zusammen mit der
‫Anfrage gesendet haben.
‫Lassen Sie uns dieses Konsolenprotokoll hier einfach schnell deaktivieren.
‫In Ordnung, und bevor wir weitermachen, sollten wir dann
‫tatsächlich überprüfen, ob das Token tatsächlich existiert.
‫Okay.
‫Wenn also kein Token
‫vorhanden ist, dann wollen wir natürlich einen neuen Fehler erstellen.
‫Richtig, und so wie zuvor kehren wir
‫von dieser Middleware zurück und rufen
‫die nächste an, okay.
‫Und hier drin werden wir dann einen Fehler
‫erstellen und gehen
‫mit diesem Fehler direkt zu unserer globalen Fehlerbehandlungs-Middleware.
‫Alles klar, wenn also kein Token mit der Anfrage gesendet wird, bedeutet
‫dies, dass wir nicht eingeloggt sind.
‫Senden wir also an den Benutzer, bei dem Sie nicht
‫angemeldet sind.
‫Bitte loggen Sie sich ein, um Zugang zu erhalten.
‫In Ordnung, und jetzt
‫ist der Statuscode für diese Art von
‫Situation 401, was bedeutet, nicht autorisiert, okay?
‫Ich bin mir nicht sicher, ob wir das schon
‫einmal benutzt haben und ja, tatsächlich haben wir es hier auch gemacht.
‫Okay, und das bedeutet im
‫Grunde, dass die Daten, die in der Anfrage gesendet wurden,
‫korrekt sind, aber im Grunde nicht ausreichen, um dem
‫Benutzer Zugriff auf eine angeforderte Ressource zu verschaffen.
‫Gut.
‫Einfach hier
‫speichern und nochmal testen.
‫Wenn wir diesen Header hier also grundsätzlich wegnehmen,
‫sollten wir sofort auf diesen Fehler eingehen,
‫oder?
‫Und tatsächlich, Sie sind nicht eingeloggt, bitte melden Sie sich
‫an, um Zugang zu erhalten.
‫Mit 401 nicht autorisiert.
‫Groß! Der Teil funktioniert also schon.
‫In Ordnung, und jetzt nur um es zusammenzufassen,
‫also senden wir im Moment kein Token zusammen mit
‫der Anfrage, oder?
‫Aus diesem Grund gibt es natürlich kein Zeichen, okay?
‫Und deshalb erstellen wir
‫diesen Fehler, der dann unsere Fehlerbehandlungs-Middleware dazu veranlasst,
‫diesen Fehler an den Client zurückzusenden, okay?
‫Und dann bekommen wir natürlich nicht auf
‫alle Touren Zugriff, denn natürlich
‫läuft diese Middleware vor dem getAllTours-Controller.
‫Und im Moment ist das wirklich geschützt, okay?
‫Es funktioniert also jetzt schon ganz gut.
‫Aber das reicht natürlich bei weitem nicht aus,
‫denn es reicht nicht, nur einen Token mit einer Anfrage zu senden.
‫Es muss auch ein gültiger Token sein.
‫Im Grunde also ein Token, bei dem niemand
‫versucht hat, die Nutzlast zu ändern.
‫Okay, und denken Sie daran, dass die Nutzlast in
‫unserem Fall immer die user_id des Benutzers ist, für den das Token ausgestellt wurde.
‫Alles klar, und als
‫nächstes müssen wir diesen Überprüfungsschritt implementieren.
‫Aber dieser Vortrag dauert schon ziemlich lange und es
‫gibt hier noch viel zu tun,
‫also lassen wir das eigentlich für das nächste Video.