‫Jonas: In questa lezione
‫implementeremo qualcosa chiamato CORS, che significa condivisione di risorse tra le origini.
‫E questa è una caratteristica fondamentale in qualsiasi API,
‫ma posso mostrartelo solo
‫ora che l'applicazione è già effettivamente distribuita.
‫Ora, cos'è in realtà la condivisione delle risorse tra le
‫origini e perché è necessario implementarla?
‫Bene, diciamo che abbiamo la nostra
‫API qui a natours-jonas. herokuapp. com/api/v1, e così
‫via.
‫E poi qualche altro sito web, ad esempio ad esempio. com, sta cercando
‫di accedere alla nostra API.
‫Quindi fondamentalmente cercando di chiamare questo URL qui.
‫E questa viene quindi chiamata richiesta di origine
‫incrociata, perché herokuapp. com è un dominio diverso
‫da example. com, e quindi quindi se example. com sta cercando
‫di accedere a herokuapp. com,
‫sarà una richiesta multiorigine, ok?
‫Ora di solito le richieste tra le origini non sono
‫consentite e per impostazione predefinita falliranno, a meno che non implementiamo CORS,
‫quindi la condivisione delle risorse tra le origini.
‫E poiché vogliamo rendere la nostra
‫API disponibile a tutti, dobbiamo assolutamente implementarla, ok?
‫Ora lascia che ti mostri effettivamente come questo fallirebbe.
‫Quindi prendiamo questo URL
‫qui, lo apriamo nella tua scheda e poi controlliamo.
‫E quindi in pratica facciamo una richiesta HTTP alla nostra API
‫qui dalla console, ok?
‫Perché fondamentalmente quando lo faremo
‫da qui, sarà anche una richiesta cross-origine.
‫Quindi diciamo solo const x uguale wait,
‫e poi usiamo la funzione fetch JavaScript, va bene?
‫Quindi fetch è fondamentalmente
‫una funzione un po' simile alla libreria
‫Axios che abbiamo usato nel
‫nostro codice, ma è JavaScript nativo nel
‫browser, quindi possiamo semplicemente usarlo qui nella console.
‫Quindi diciamo che vogliamo fare una
‫richiesta alla nostra API dei tour in questo modo, va bene?
‫Quindi, se proviamo questo ora, vediamo cosa otteniamo.
‫E infatti otteniamo
‫l'errore che il tentativo di accedere a
‫questo percorso qui da quest'altra origine è stato bloccato dalla politica CORS.
‫E quindi è esattamente quello che ho detto prima.
‫In questo modo, per impostazione predefinita, una richiesta tra
‫le origini verrà sempre bloccata.
‫A proposito, questo vale solo per le richieste
‫effettuate dal browser.
‫Ad esempio, utilizzando l'API fetch qui o qualcosa
‫come la libreria Axios che abbiamo
‫usato nel nostro codice.
‫E quindi ciò significa che
‫dal server saremo sempre in grado di effettuare richieste
‫cross-origin senza problemi.
‫Quindi non ci sono restrizioni sul server,
‫ma in realtà solo
‫sul browser, per ragioni di sicurezza sostanzialmente.
‫Oh, e anche per essere considerata cross-origine, una richiesta
‫potrebbe provenire da un dominio diverso.
‫Quindi, proprio come abbiamo visto nel nostro
‫primo esempio qui, ma anche un sottodominio diverso, un
‫protocollo diverso o anche una porta diversa
‫è considerato una richiesta cross-origin.
‫Quindi, ad esempio, se avessimo API. natours. com per la nostra API,
‫e quindi farebbe una richiesta da natours. com, anche questa
‫verrebbe considerata una richiesta multiorigine e non
‫andrebbe a buon fine, ok?
‫Ma ancora una volta, poiché vogliamo consentire ad altri
‫siti Web di accedere sostanzialmente alla nostra
‫API, implementiamo ora la condivisione delle risorse tra le origini.
‫Va bene, quindi lo facciamo ancora una volta
‫installando un pacchetto NPM.
‫Quindi installa NPM e semplicemente CORS.
‫Allora qui abbiamo bisogno di quel pacchetto.
‫E ancora una volta, questo CORS
‫è una funzione middleware
‫molto semplice che ora dobbiamo usare per la nostra applicazione, va bene?
‫Quindi facciamolo qui, e perché non farlo proprio
‫qui in alto?
‫Quindi diciamo implementare CORS.
‫E così app. use, quindi chiama CORS, che
‫a sua volta restituirà una funzione middleware
‫che aggiungerà un paio di intestazioni diverse
‫alla nostra risposta.
‫E poiché tutta questa funzione del middleware
‫qui è sostanzialmente di aggiungere alcune intestazioni specifiche, forse
‫stai pensando "Perché stiamo usando" l'ennesimo
‫pacchetto NPM? "Bene, diamo
‫solo un'occhiata al codice
‫di questo pacchetto.
‫Quindi GitHub CORS, quindi ancora una volta, di
‫solito è così che trovo la documentazione o il
‫codice sorgente stesso per i miei pacchetti.
‫E quindi andiamo qui in lib, che
‫di solito significa libreria.
‫E poi tutto quello che abbiamo davvero qui è questo indice. js.
‫E quindi vedi che qui c'è tutto il codice, e
‫fondamentalmente quello che
‫vedi qui è che aggiunge semplicemente questa
‫intestazione qui con il valore di praticamente tutto alle intestazioni.
‫Bene, allora hai un paio di altre
‫intestazioni, Access-Control-Allow-Methods, allow-credentials, e questo è
‫per diversi casi.
‫Va bene, ma così vedi
‫che qui si tratta solo di intestazioni.
‫Quindi sì, forse potremmo semplicemente aggiungere queste intestazioni da soli,
‫ma perché dovremmo farlo davvero?
‫Voglio dire che
‫potremmo ovviamente, per capire appieno come funziona, ma
‫in Node. js e
‫sviluppo Express, nell'ambiente reale di solito
‫non vorrai reinventare la ruota e invece,
‫ogni volta che puoi, usa
‫i pacchetti che altri sviluppatori hanno scritto per noi.
‫Quindi in realtà ci concentriamo solo sul far funzionare la
‫nostra applicazione, invece di riscrivere il codice
‫che altri sviluppatori hanno già scritto per noi, va bene?
‫Quindi possiamo dare un'occhiata a
‫tutto questo, ma come ho detto, possiamo anche andare
‫avanti e usare effettivamente questo, va bene?
‫Ad ogni modo, è così che abilitiamo la condivisione delle risorse tra le origini per
‫tutte le richieste in arrivo.
‫Quindi fondamentalmente per tutta la nostra API.
‫Ma diciamo che volevamo solo abilitare CORS
‫su un percorso specifico.
‫Quindi potremmo usare anche quello, quindi copiamo questo.
‫Quindi, se volessimo solo abilitare CORS, diciamo durante
‫i tour, potremmo
‫semplicemente aggiungerlo qui in questo stack middleware.
‫Va bene, ma anche in questo caso
‫vogliamo davvero consentirlo ovunque.
‫Quindi, come abbiamo visto in precedenza
‫nel codice
‫GitHub, ciò che fa è impostare l'intestazione Access-Control-Allow-Origin su tutto.
‫E quindi ciò che questo significa
‫tutto qui è per tutte le richieste, non importa da dove provengano.
‫E quindi questo è l'ideale per consentire a
‫tutti di utilizzare la nostra API.
‫Ma ora immagina il
‫caso in cui non vogliamo condividere la nostra
‫API, ma vogliamo essere in grado di avere l'API su
‫un dominio, o anche un sottodominio, e quindi
‫avere la nostra applicazione front-end su un dominio diverso.
‫Ad esempio, diciamo, come ho detto prima, avevamo la nostra
‫API in API. natours. com, ma poi
‫la nostra app front-end su natours. com.
‫E quindi in quel caso tutto
‫ciò che vogliamo che faccia è consentire l'accesso da questa origine qui, in pratica.
‫E quindi in quel caso useremmo app. use, quindi CORS, quindi
‫passare un oggetto per le opzioni in cui
‫specificheremmo l'origine, ad
‫esempio HTTPS://www. natours. com.
‫E quindi questo è solo un
‫esempio nel caso avessimo il nostro front-end a natours. com, va bene?
‫E così di nuovo, con questo consentiremmo fondamentalmente
‫solo a questo URL, quindi a questa origine,
‫di creare richieste all'API. natours. com.
‫E naturalmente potremmo anche ammettere altre origini.
‫Ad esempio, solo per alcuni
‫siti Web specifici che vogliamo consentire, ok?
‫Ma ancora una volta, in questo caso vogliamo davvero permettere a tutti.
‫Ok, questa è stata la prima parte dell'abilitazione di CORS,
‫ma in realtà non è tutto,
‫perché in questo momento funzionerà
‫solo per le cosiddette richieste semplici.
‫E le richieste semplici sono le richieste di ricezione e pubblicazione.
‫D'altra parte, abbiamo le cosiddette richieste non semplici.
‫E queste sono richieste di inserimento, correzione ed eliminazione,
‫o anche richieste che inviano cookie
‫o utilizzano intestazioni non standard.
‫E queste non semplici
‫richieste, richiedono una cosiddetta fase di preflight.
‫Quindi, ogni volta che c'è una richiesta non
‫semplice, il browser emetterà automaticamente
‫la fase di preflight, ed è così che funziona.
‫Quindi, prima che la vera richiesta si verifichi
‫effettivamente, e diciamo una richiesta di
‫eliminazione, il browser esegue prima una richiesta di opzioni
‫per capire se la richiesta effettiva è
‫sicura da inviare.
‫E quindi ciò che significa per noi
‫sviluppatori è che sul nostro server dobbiamo effettivamente rispondere
‫a quella richiesta di opzioni.
‫E le opzioni sono in realtà solo un
‫altro metodo HTTP, quindi proprio come ottenere, pubblicare o eliminare, va bene?
‫Quindi, in pratica, quando riceviamo una di queste
‫richieste di opzioni sul nostro
‫server, dobbiamo inviare la stessa intestazione Access-Control-Allow-Origin.
‫E in questo modo il browser saprà
‫che la richiesta
‫effettiva, e in questo caso la richiesta di eliminazione, è
‫sicura da eseguire, e quindi eseguirà la richiesta di eliminazione stessa, va bene?
‫Quindi facciamolo e diciamo app. opzioni.
‫Ok, e quindi di nuovo questo è molto simile a
‫fare app. ottenere per esempio, o . inviare, . Elimina, . patch, e
‫tutti questi verbi che già conosci.
‫Così . options non è impostare alcuna opzione sulla
‫nostra applicazione, è in realtà solo un altro metodo HTTP a cui possiamo rispondere.
‫E così ancora, in questo caso dobbiamo rispondere perché
‫il browser invia una richiesta di
‫opzione quando c'è una fase di preflight.
‫Quindi dobbiamo definire il
‫percorso per il quale vogliamo gestire le opzioni.
‫E ancora una volta, lo faremo su tutte le rotte, ok?
‫E poi fondamentalmente il gestore,
‫che ancora una volta è il middleware CORS, va bene?
‫E ancora una volta, potremmo ovviamente
‫consentire queste richieste complesse solo su un percorso specifico.
‫Ad esempio app. opzioni,
‫e diciamo solo su
‫api/v1/tours/:id, così, ok?
‫Quindi diciamo che qualcuno fa una cancellazione o una richiesta di
‫patch per uno dei tour, e solo
‫lì permettiamo una fase di preflight.
‫E quindi fondamentalmente solo su questo
‫percorso qui, una di queste richieste complesse può essere fatta.
‫Quindi in questo caso qui dove avevamo solo questo percorso di opzioni,
‫solo i tour potevano essere eliminati
‫o corretti da una richiesta multiorigine, giusto?
‫E nessuna delle nostre altre risorse, va bene?
‫Ma ancora una volta, permettiamoli tutti, ok?
‫Ma lascerò ancora questo qui per te come esempio.
‫Ok, comunque, è tutto ciò che dobbiamo fare per
‫abilitare CORS per la nostra applicazione.
‫E quindi ora ridistribuiamo l'applicazione spingendola
‫di nuovo su Heroku.
‫Ma prima di farlo, in realtà voglio cambiare qualcosa qui
‫nel nostro pacchetto. json.
‫E questo è questo motore del nodo qui.
‫Quindi a volte può creare dei
‫problemi quando specifichiamo la versione in questo modo.
‫Quindi, in pratica, consentire l'installazione di
‫versioni superiori alla versione
‫attualmente in esecuzione.
‫E quindi quello che
‫voglio fare qui è dire che dovrebbe installare solo la versione
‫10 e non una versione successiva.
‫Quindi lo faccio dicendo questo simbolo caret qui, e poi
‫la versione 10.
‫E così ancora una volta, questo sta usando il versionamento semantico,
‫e così proprio come qui.
‫Il che, ricorda, significa che a
‫NPM è consentito installare una qualsiasi di queste subversioni o
‫versioni di patch, ma non passare alla versione principale successiva.
‫E quindi qui quello che sto facendo è lo stesso, ok?
‫Quindi attualmente sto eseguendo Node versione 10 qualcosa,
‫quindi puoi confermare la tua digitando node -v, e quindi vedi che
‫sono su 10. 11 in questo momento.
‫Ma probabilmente quando guarderai questo
‫corso, sarai almeno alla versione 12, forse anche 14 o 16, a seconda
‫di quanto tempo sarai nel futuro, va bene?
‫E non preoccuparti, ovviamente, tutto
‫ciò che ti mostro qui nel corso dovrebbe
‫ancora funzionare correttamente
‫per qualsiasi versione di Node che stai utilizzando.
‫Quindi, se stai usando la
‫versione 12, per favore vai avanti e metti il 12 proprio qui, ok?
‫Ad ogni modo, ora aggiungiamo tutti
‫i file modificati all'area di staging, quindi aggiungi tutto.
‫E poi impegnarli con un messaggio significativo, quindi
‫implementato CORS.
‫E poi spingi il maestro Heroku.
‫E ora ci vuole un po'
‫di tempo, quindi ci vediamo quando sarà finito.
‫Quindi l'applicazione è stata distribuita con successo ora, ricarichiamo
‫rapidamente qui solo per vedere
‫se funziona ancora, e in effetti lo è.
‫E quindi ora per dimostrarti che funziona in modo diverso con
‫CORS, se ripetiamo
‫questa richiesta qui dovrebbe funzionare effettivamente, giusto?
‫Quindi proviamoci e ci siamo.
‫Nessun errore questa volta, controlliamo x qui.
‫E infatti, sembra che ci sia qualcosa qui.
‫Quindi vedi che in realtà la risposta è di tipo
‫CORS, abbiamo le nostre intestazioni, beh, non riesco davvero a vederle qui.
‫Non importa, qui abbiamo anche solo
‫una stringa leggibile, ma
‫ancora una volta non è affatto importante.
‫Ciò che conta qui è
‫che ora siamo in grado di eseguire richieste multiorigine, quindi è fantastico.
‫Ora lascia che ti mostri anche le
‫intestazioni effettive che il
‫pacchetto CORS aggiunge semplicemente facendo qualche richiesta qui in Postman.
‫Quindi in produzione, ora lo mandiamo.
‫E così qui puoi
‫vedere nelle intestazioni di risposta che in
‫realtà abbiamo questo Access-Control-Allow-Origin impostato su tutto, ok, fantastico.
‫Ed è così che si implementa effettivamente la condivisione
‫delle risorse tra le origini nella propria applicazione.