‫Jonas: In diesem Vortrag
‫implementieren wir etwas namens CORS, was ursprungsübergreifende gemeinsame Nutzung von Ressourcen bedeutet.
‫Und dies ist eine grundlegende Funktion in jeder API, aber ich
‫kann Ihnen dies nur
‫jetzt zeigen, da die Anwendung tatsächlich bereits bereitgestellt ist.
‫Was ist nun eigentlich Cross-Origin-Resource-Sharing und warum
‫müssen wir es implementieren?
‫Nehmen wir an, wir haben unsere
‫API hier bei natours-jonas. herokuapp. com/api/v1 usw.
‫usw.
‫Und dann eine andere Website, zum Beispiel bei Beispiel. com, versucht,
‫auf unsere API zuzugreifen.
‫Versuchen Sie also im Grunde, diese URL hier aufzurufen.
‫Und das nennt man dann ursprungsübergreifende Anfrage,
‫denn herokuapp. com ist eine andere Domäne
‫als example. com, und so daher, wenn Beispiel. com versucht,
‫auf herokuapp zuzugreifen. com, es
‫wird eine ursprungsübergreifende Anfrage sein, in Ordnung?
‫Jetzt sind normalerweise ursprungsübergreifende Anfragen nicht zulässig
‫und schlagen standardmäßig fehl, es sei denn, wir
‫implementieren CORS, also ursprungsübergreifende Ressourcenfreigabe.
‫Und da wir unsere API allen zur
‫Verfügung stellen wollen, müssen wir das unbedingt implementieren, ja?
‫Lassen Sie mich Ihnen nun tatsächlich zeigen, wie dies fehlschlagen würde.
‫Lassen Sie uns diese URL
‫hier abrufen, in Ihrem Tab öffnen und dann überprüfen.
‫Lassen Sie uns also im Grunde eine HTTP-Anfrage an unsere API hier von
‫der Konsole aus senden, okay?
‫Denn im Grunde wird es, wenn wir es
‫von hier aus tun, auch eine ursprungsübergreifende Anfrage sein.
‫Sagen wir also einfach const x gleich
‫await und verwenden wir dann die JavaScript-Abruffunktion, in Ordnung?
‫fetch ist also im Grunde
‫eine Funktion, die der Axios-Bibliothek, die wir in unserem
‫Code verwendet haben, ein bisschen ähnlich ist,
‫aber es ist natives JavaScript im Browser, und
‫wir können es also einfach hier in der Konsole verwenden.
‫Nehmen wir an, wir möchten
‫eine Anfrage an unsere Touren-API wie diese stellen, in Ordnung?
‫Wenn wir das jetzt versuchen, schauen wir mal, was wir bekommen.
‫Und tatsächlich erhalten
‫wir den Fehler, dass der Versuch, von
‫diesem anderen Ursprung aus auf diesen Pfad zuzugreifen, durch die CORS-Richtlinie blockiert wurde.
‫Und genau das habe ich vorhin gesagt.
‫Damit wird eine ursprungsübergreifende Anfrage
‫standardmäßig immer blockiert.
‫Dies gilt übrigens nur für Anfragen
‫aus dem Browser.
‫Zum Beispiel die Verwendung der fetch-API hier oder etwas
‫wie die Axios-Bibliothek, die wir in
‫unserem Code verwendet haben.
‫Das bedeutet, dass wir
‫vom Server aus immer problemlos Cross-Origin-Anfragen
‫stellen können.
‫Es gibt also keine Einschränkungen auf dem
‫Server, sondern eigentlich nur
‫auf dem Browser, aus Sicherheitsgründen grundsätzlich.
‫Oh, und auch um als ursprungsübergreifend angesehen zu werden, kann
‫eine Anfrage von einer anderen Domäne stammen.
‫So wie wir in unserem ersten Beispiel
‫hier gesehen haben, wird aber auch eine andere Subdomain,
‫ein anderes Protokoll oder sogar ein
‫anderer Port als Cross-Origin-Request gewertet.
‫Wenn wir zum Beispiel eine API hätten. Natur. com für unsere API und
‫würde dann eine Anfrage von natours stellen. com, das
‫wäre dann auch eine Cross-Origin-Anfrage
‫und würde fehlschlagen, okay?
‫Da wir jedoch anderen Websites grundsätzlich den
‫Zugriff auf unsere API ermöglichen
‫möchten, implementieren wir nun die ursprungsübergreifende Ressourcenfreigabe.
‫In Ordnung, und das tun wir noch einmal,
‫indem wir ein NPM-Paket installieren.
‫Also NPM installieren und einfach CORS.
‫Dann brauchen wir hier dieses Paket.
‫Und noch einmal, dieser CORS
‫hier ist eine sehr
‫einfache Middleware-Funktion, die wir jetzt für unsere Anwendung verwenden müssen, in Ordnung?
‫Also machen wir das hier, und warum nicht
‫gleich hier oben?
‫Nehmen wir an, wir implementieren CORS.
‫Und so App. use, und rufen Sie dann
‫CORS auf, was wiederum eine Middleware-Funktion zurückgibt,
‫die dann unserer Antwort ein paar
‫verschiedene Header hinzufügt.
‫Und da diese Middleware-Funktion hier im
‫Grunde darin besteht, einige spezifische Header hinzuzufügen, denken
‫Sie vielleicht: "Warum verwenden wir" noch
‫ein NPM-Paket? "Nun, schauen
‫wir uns einfach mal den
‫Code dieses Pakets an.
‫Also GitHub CORS, also noch einmal, so
‫finde ich normalerweise die Dokumentation oder den
‫Quellcode selbst für meine Pakete.
‫Lassen Sie uns hier also zu lib gehen,
‫was normalerweise Bibliothek bedeutet.
‫Und dann haben wir hier wirklich nur diesen Index. js.
‫Sie sehen also, dass hier der gesamte Code ist, und im
‫Wesentlichen sehen Sie
‫hier, dass dieser Header hier einfach mit dem
‫Wert von im Wesentlichen allem zu den Headern hinzugefügt wird.
‫In Ordnung, dann haben Sie ein paar
‫andere Header, Access-Control-Allow-Methods, allow-credentials, und das
‫für verschiedene Fälle.
‫Alles klar, aber Sie sehen, dass
‫es hier wirklich nur um Kopfzeilen geht.
‫Also ja, vielleicht könnten wir diese Header einfach selbst hinzufügen, aber
‫warum sollten wir das eigentlich tun?
‫Ich meine, wir könnten
‫natürlich, um wirklich zu verstehen, wie es funktioniert, aber
‫in Node. js- und Express-Entwicklung
‫werden Sie in der realen Umgebung
‫normalerweise das Rad nicht neu erfinden wollen
‫und stattdessen, wann immer Sie
‫können, Pakete verwenden, die andere Entwickler für uns geschrieben haben.
‫Wir konzentrieren uns also wirklich darauf, dass unsere Anwendung funktioniert,
‫anstatt Code neu zu schreiben, den
‫andere Entwickler bereits für uns geschrieben haben, in Ordnung?
‫Wir können uns
‫das also alles anschauen, aber wie gesagt, wir
‫können es auch einfach verwenden, okay?
‫Auf jeden Fall ermöglichen wir auf diese Weise die ursprungsübergreifende Ressourcenfreigabe
‫für alle eingehenden Anfragen.
‫Also im Grunde für unsere gesamte API.
‫Aber sagen wir, wir wollten CORS nur auf
‫einer bestimmten Route aktivieren.
‫Wir könnten das also auch verwenden, also kopieren wir das einfach.
‫Wenn wir also nur CORS, sagen wir auf den
‫Touren, aktivieren wollten, könnten
‫wir das einfach hier in diesen Middleware-Stack einfügen.
‫Alles klar, aber auch in diesem Fall wollen
‫wir es wirklich überall zulassen.
‫Wie wir bereits im GitHub-Code
‫gesehen
‫haben, wird der Header Access-Control-Allow-Origin auf alles gesetzt.
‫Und das alles hier
‫bedeutet also für alle Anfragen, egal woher sie kommen.
‫Dies ist also ideal, damit jeder
‫unsere API nutzen kann.
‫Stellen Sie sich nun
‫den Fall vor, in dem wir unsere
‫API nicht teilen möchten, sondern die API in einer Domäne
‫oder sogar einer Unterdomäne haben möchten und
‫dann unsere Front-End-Anwendung in einer anderen Domäne haben.
‫Nehmen wir zum Beispiel an, wie ich bereits erwähnt habe, hatten wir
‫unsere API bei API. Natur. com, aber dann
‫unsere Frontend-App bei natours. com.
‫In diesem Fall wollen wir
‫also nur den Zugriff von diesem Ursprung hier im Grunde erlauben.
‫In diesem Fall würden wir die App verwenden. use und dann CORS, und
‫übergeben Sie dann ein Objekt für die Optionen, bei denen
‫wir den Ursprung angeben
‫würden, beispielsweise HTTPS://www. Natur. com.
‫Dies ist also nur ein Beispiel für
‫den Fall, dass wir unser Frontend bei natours hatten. com, in Ordnung?
‫Und damit würden wir im Grunde nur
‫dieser URL, also diesem Ursprung, erlauben, Anfragen an
‫die API zu erstellen. Natur. com.
‫Und natürlich könnten wir auch andere Ursprünge zulassen.
‫Zum Beispiel nur für einige
‫bestimmte Websites, die wir zulassen möchten, okay?
‫Aber auch in diesem Fall wollen wir wirklich alle zulassen.
‫Okay, das war der erste Teil der Aktivierung von CORS,
‫aber das ist noch nicht alles,
‫denn im Moment funktioniert
‫dies nur für sogenannte einfache Anfragen.
‫Und einfache Anfragen sind Get- und Post-Requests.
‫Auf der anderen Seite haben wir sogenannte nicht-einfache Anfragen.
‫Und dies sind Put-, Patch- und Delete-Anfragen oder
‫auch Anfragen, die Cookies senden oder
‫nicht standardmäßige Header verwenden.
‫Und diese nicht
‫einfachen Anfragen erfordern eine sogenannte Preflight-Phase.
‫Wenn es also eine nicht einfache Anfrage
‫gibt, gibt der Browser
‫automatisch die Preflight-Phase aus, und so funktioniert das.
‫Bevor also die eigentliche Anfrage auftritt,
‫beispielsweise eine Löschanfrage, führt
‫der Browser zunächst eine Optionsanfrage aus, um
‫herauszufinden, ob die eigentliche Anfrage sicher
‫gesendet werden kann.
‫Für uns Entwickler bedeutet dies,
‫dass wir auf unserem Server tatsächlich auf
‫diese Optionsanfrage antworten müssen.
‫Und options ist wirklich nur eine weitere
‫HTTP-Methode, also genau wie get, post oder delete, in Ordnung?
‫Wenn wir also eine dieser Optionsanfragen auf
‫unserem Server erhalten, müssen
‫wir im Grunde denselben Access-Control-Allow-Origin-Header zurücksenden.
‫Auf diese Weise weiß der Browser
‫dann, dass die
‫eigentliche Anfrage, und in diesem Fall die Löschanfrage, sicher
‫durchgeführt werden kann, und führt dann die Löschanfrage selbst aus, in Ordnung?
‫Also lass uns das tun und sagen App. Optionen.
‫Okay, und das ist wieder sehr ähnlich wie bei
‫der App. erhalten zum Beispiel, oder . Post, . löschen, . patch, und
‫all diese Verben, die Sie bereits kennen.
‫So . options ist nicht das Setzen von Optionen
‫für unsere Anwendung, sondern nur eine weitere HTTP-Methode, auf die wir reagieren können.
‫Auch in diesem Fall müssen wir darauf
‫reagieren, da der Browser
‫in einer Preflight-Phase eine Optionsanfrage sendet.
‫Wir müssen also die
‫Route definieren, für die wir die Optionen behandeln möchten.
‫Und das machen wir wieder auf allen Strecken, okay?
‫Und dann im Grunde
‫der Handler, der wiederum die CORS-Middleware ist, in Ordnung?
‫Und wieder einmal konnten wir diese
‫komplexen Anfragen natürlich nur auf einer bestimmten Strecke zulassen.
‫Zum Beispiel App. Optionen,
‫und sagen wir nur auf
‫api/v1/tours/:id, so, okay?
‫Nehmen wir also an, jemand macht einen Lösch- oder Patch-Request
‫für eine der Touren, und nur
‫dort erlauben wir eine Preflight-Phase.
‫Und so kann im Grunde nur
‫auf dieser Strecke hier eine dieser komplexen Anfragen erledigt werden.
‫Also in diesem Fall hier, wo wir nur diese Routenoptionen hatten,
‫konnten nur die Touren aus
‫einer Cross-Origin-Anfrage gelöscht oder gepatcht werden, oder?
‫Und keine unserer anderen Ressourcen, in Ordnung?
‫Aber noch einmal, lassen Sie uns alle zulassen, okay?
‫Aber ich lasse dies dennoch nur als Beispiel hier für Sie.
‫Okay, das ist alles, was wir wirklich tun müssen,
‫um CORS für unsere Anwendung zu aktivieren.
‫Lassen Sie uns die Anwendung jetzt erneut bereitstellen,
‫indem Sie sie erneut an Heroku übertragen.
‫Aber bevor wir das tun, möchte ich hier in unserem Paket
‫noch etwas ändern. json.
‫Und das ist diese Node-Engine hier.
‫Daher kann es manchmal zu
‫Problemen kommen, wenn wir die Version so angeben.
‫Also grundsätzlich erlauben, dass Versionen installiert werden, die
‫größer sind als die Version,
‫die wir derzeit ausführen.
‫Ich möchte hier
‫also sagen, dass nur Version 10 installiert werden
‫sollte und keine Version danach.
‫Also mache ich es, indem ich hier dieses Caret-Symbol sage und
‫dann Version 10.
‫Und das ist wieder einmal die semantische Versionierung,
‫und so wie hier.
‫Denken Sie daran, dass NPM
‫jede dieser Unterversionen oder Patch-Versionen installieren darf, aber
‫nicht auf die nächste Hauptversion aufsteigen darf.
‫Und hier, was ich tue, ist dasselbe, okay?
‫Ich verwende derzeit also etwas Node-Version 10, und Sie
‫können Ihre bestätigen, indem Sie node -v eingeben, und Sie sehen, dass ich
‫auf 10 bin. 11 jetzt.
‫Aber wahrscheinlich, wenn Sie sich diesen
‫Kurs ansehen, werden Sie mindestens bei Version 12, vielleicht sogar 14 oder 16 sein, je
‫nachdem, wie lange Sie in der Zukunft sind, in Ordnung?
‫Und machen Sie sich natürlich
‫keine Sorgen, alles, was ich Ihnen hier im Kurs
‫zeige, sollte für
‫die von Ihnen verwendete Node-Version immer noch gut funktionieren.
‫Wenn Sie also Version
‫12 verwenden, legen Sie die 12 bitte hier ein, okay?
‫Wie auch immer, fügen wir jetzt alle
‫geänderten Dateien zum Staging-Bereich hinzu, also git add all.
‫Und sie dann mit einer aussagekräftigen Nachricht festschreiben,
‫so implementiert CORS.
‫Und dann hol dir den Heroku-Meister.
‫Und das dauert jetzt einige Zeit,
‫also sehen wir uns, wenn das erledigt ist.
‫Die Anwendung ist jetzt also erfolgreich bereitgestellt. Laden wir sie
‫hier kurz neu, um zu sehen,
‫ob sie noch funktioniert, und das ist sie tatsächlich.
‫Und nun, um Ihnen zu beweisen, dass es mit CORS anders funktioniert, wenn wir
‫diese Anfrage hier noch
‫einmal ausführen, sollte es dann tatsächlich funktionieren, oder?
‫Versuchen wir es also und los geht's.
‫Diesmal kein Fehler, lass uns hier x überprüfen.
‫Und tatsächlich sieht es so aus, als ob hier etwas wäre.
‫Sie sehen also, dass die Antwort tatsächlich vom Typ CORS
‫ist, wir haben unsere Header, nun, ich kann sie hier nicht wirklich sehen.
‫Das macht nichts, hier haben wir auch
‫nur einen lesbaren String,
‫aber auch das ist überhaupt nicht wichtig.
‫Wichtig ist hier, dass
‫wir jetzt ursprungsübergreifende Anfragen durchführen können, das ist fantastisch.
‫Lassen Sie mich Ihnen nun auch die tatsächlichen
‫Header zeigen, die das
‫CORS-Paket hinzufügt, indem Sie einfach eine Anfrage hier in Postman ausführen.
‫Lassen Sie es uns jetzt in der Produktion senden.
‫Und hier sehen Sie
‫also in den Antwortheadern, dass wir dieses
‫Access-Control-Allow-Origin tatsächlich auf alles gesetzt haben, okay, toll.
‫So implementieren Sie also tatsächlich die ursprungsübergreifende
‫Ressourcenfreigabe in Ihrer eigenen Anwendung.