[MUSIC]
Avevamo già sviluppato un server API REST completo usando Express e
MongoDB come parte di questo corso.
Affinché il server sia in grado di comunicare in modo significativo con il nostro cliente,
faremo alcune piccole modifiche ad esso in modo che restituisca il giusto tipo di dati.
In modo che la nostra implementazione client possa funzionare in modo più efficiente
con i dati restituiti dal nostro lato server.
Quindi, per farlo,
lavoriamo su alcuni aggiustamenti al nostro lato server in questo esercizio.
Andando al nostro server nell'editor, prima di iniziare a lavorare sul server,
ti suggerisco di scaricare tutte le immagini che ho fornito
come file zip nelle risorse di esercizio chiamate images.zip.
Decomprimere il file e quindi ottenere tutte le immagini da lì, e
quindi copiare quelle immagini nella cartella immagini pubbliche nel nostro server.
Quindi vedi che qui ho
già copiato tutte le immagini nella mia cartella di immagini pubbliche qui.
Perché il nostro server è quello che servirà tutte queste immagini per la
nostra applicazione client.
Successivamente, andiamo ai cors e aggiustiamo quella whitelist, qui.
Quindi, per la nostra applicazione client Angular, se la avviamo
con il comando ng serve, viene eseguito in localhost: 4200.
Quindi qualsiasi richiesta proveniente dalla nostra
applicazione Angular al server lo porterà come origine lì.
Ecco perché ho intenzione di aggiungerlo nella mia whitelist, in modo
che eventuali problemi cors vengano risolti automaticamente.
Quindi andando in quel file cors.js,
nella mia whitelist, qui, lasciami aggiungere
il http://localhost:, 4200.
E questa è l'origine da cui tutto il mio client Angular
originerà la richiesta che arriva a questo server.
In questo modo, i miei cors non causeranno problemi per il client angolare di maggio.
Successivamente, abbiamo bisogno di aggiornare alcuni dei percorsi per gestire
i parametri di query e anche alcuni piccoli altri aggiustamenti.
Permettetemi di iniziare con i file promoRouter.js.
Quindi questo è semplice da aggiornare.
Quindi andando al file promoRouter.js, nel file PromorOuter, per
la richiesta get che arriviamo qui,
invece di fare promotions.Find con un JavaScript vuoto,
qui vorrei fornire il req.query come
parametro a quel promotions.Find qui.
Stessa cosa anche con LeaderRouter, quindi lasciami andare al file leaderRouter.js.
E anche in LeaderRouter,
qui dove trovi Leaders.Find con l'oggetto JavaScript vuoto.
Invece, sostituirlo con quel req.query, in modo
che i parametri della query vengano passati.
Quindi questo è dove passeremo nella colonna in primo piano
attraverso come parametro di query.
Ora dopo aver regolato questi due, lavoriamo ora sul percorso piatto,
quindi andando al file dishRouter.js, anche nel DishRouter, lo stesso aggiornamento qui.
Quindi andando a questo piatti.Find nel metodo get qui, cambialo in req.query.
Quindi con questo, il mio aggiornamento DishRouter è stato completato.
Quindi ora abbiamo aggiornato il PromorOuter, il ReaderRouter e
il DishRouter, quindi passeremo ad aggiornare quel FavoriteRouter.
Ora avresti implementato il router preferito come parte del tuo
quarto incarico.
Ora nel FavoriteRouter, vedrai che per
il FavoriteRouter non ti sto mostrando la parte rimanente perché
avresti dovuto fare come parte del tuo incarico.
Permettetemi di attirare la vostra attenzione
sul metodo get per FavoriteRouter.route («/:dishid').
Ora, userò questo metodo get
per verificare che il piatto specifico con
un dishId sia già uno dei preferiti per l'utente.
Quindi, invece di dire semplicemente l'operazione GET non supportata,
ho solo intenzione di sfruttare la presenza di questa operazione get.
E poi diremo,
preferiti.Findone.
E dirò,
utente: req.user.id.
Quindi troveremo i preferiti per quel particolare utente.
E poi diremo, .then, preferiti.
E, catch (((err),
next (err)).
E poi allo stesso modo qui, aggiungeremo l'errore qui.
Avanti (err)), qui.
Quindi all'interno di questo.then, quando otteniamo i favoriti,
allora controlleremo, se (! preferiti).
Quindi, se non ci sono preferiti per questo utente,
allora ovviamente il piatto che stiamo controllando non esiste.
Quindi torneremo, res.statusCode, 200.
SetHeader ('Content-Type
'' application/json ').
E poi torneremo,
dicendo, «esiste»: falso.
Quindi quello che stiamo specificando qui è che se il get è fatto
a questo endpoint con un dishId, questo flag esiste qui
sarà impostato su true se questo piatto fa parte dei miei preferiti.
Se questo piatto non fa parte dei miei preferiti, imposterò il flag esiste su false.
Quindi qui, vedi che dal momento che non ho alcun favorito, quindi
esiste dovrebbe essere automaticamente falso a questo punto.
Quindi diremo «esiste»: falso, e poi restituiremo i preferiti, qui.
Beh, ovviamente in questo caso,
i favoriti sarebbero nulli a questo punto, altrimenti.
Quindi il che significa che i favoriti non sono nulli, quindi diremo se,
(favorites.dish.indexOf),
quindi stiamo andando a cercare req.params.
DishID, quindi stiamo andando a cercare questo.
favorites.dishes.array, per vedere se esiste piatto lì dentro.
E se non esiste, ovviamente questo restituirà un indice negativo qui.
Quindi anche in questo caso, restituirò esattamente lo stesso di qui.
Quindi, se restituisce un indice negativo,
significa che anche se questo particolare utente ha un centro preferito.
Questo piatto specifico non esiste nella lista il
suo preferito, quindi è per questo che restituirà esistono false qui.
Ora altrimenti ciò significa che il piatto esiste nella lista dei preferiti.
Quindi in questo caso, restituirò il codice di stato 200 esiste è vero.
In questo modo quando l'utente esegue un'operazione get su
questo punto finale con /favorite/dishId.
Dove il dishId viene fornito come parametro qui.
Come il parametro record qui,
allora controlleremo per vedere se quel piatto esiste nei preferiti.
Se nessuno dei preferiti esiste per questo utente, allora restituiremo un falso esistere.
Allo stesso modo, se i preferiti esistono,
ma quel piatto particolare non esiste nei preferiti, restituirà un falso.
Altrimenti restituirà un vero.
Quindi questa bandiera esiste può essere utilizzata dal mio cliente
per verificare se questo piatto fa parte della lista dei piatti preferiti per questo utente o meno.
Infine aggiorneremo il file users.js.
Ora nel file users.js, dobbiamo aggiungere in
un altro campo router.options qui perché
a volte una richiesta Post come hai visto con il login,
invieremo prima le opzioni per verificare, specialmente con le auto,
se la richiesta di post sarà consentita.
Ecco perché controlleranno le auto, le auto con opzioni qui e poi.
Restituiremo semplicemente
un messaggio di stato di 200 in risposta a questo.
Quindi per qualsiasi endpoint sotto gli utenti se abbiamo ricevuto
le opzioni restituirà semplicemente uno stato 200 qui.
Ora la funzione Login che avevamo implementato in precedenza.
Abbiamo semplicemente fatto passport.authenticate ('local') qui e
poi controlliamo i valori rimanenti qui.
Ora questo passport.authenticate ('local'), se l'utente non viene
autenticato, restituisce semplicemente un non autorizzato nel messaggio di risposta.
Ora questo potrebbe non essere molto significativo per
il lato client visualizzare queste informazioni.
Ecco perché miglioreremo questo metodo di login post router in modo
tale che l'autenticazione restituirà informazioni più significative in questa parte.
Quindi, per farlo, non faremo l'
autenticazione del passaporto qui dentro.
Invece, prenderemo, quindi lasciami rimuovere da lì,
e poi vedrai come aggiornerò il post del router qui.
Quindi vedremo AutosWithOptions.
E poi includeremo il req, res e il prossimo qui.
E all'interno del req, res, e il
prossimo qui, passport.authenticate,
lo chiameremo con 'local'.
Ora, quando chiamiamo questo con local, se
si verifica un errore di autenticazione, passport.authenticate può essere fatto per restituire il valore di errore,
e inoltre restituirà l'utente se non ci sono errori.
E potrebbe parametro chiamato info,
che porterà informazioni aggiuntive che potrebbero essere passate all'utente.
Questo errore verrà restituito quando si verifica un errore autentico che si verifica
nel possibile per l'autenticazione.
Ma se le informazioni dell'utente vengono inviate a passport.authenticate ma
l'utente non esiste, allora non viene conteggiato come un errore.
Invece, verrà conteggiato come utente non esiste.
E quell'informazione viene passata di nuovo nell'oggetto info che entra in.
Quindi l'errore verrà restituito quando c'è un errore genuino che si verifica durante
il processo di autenticazione.
Ma le informazioni, conterranno informazioni se l'utente non esiste e quindi
passport.authenticate sta passando un messaggio che dice che l'utente non
esiste o che il nome utente non è corretto o che la password non è corretta.
E così via, in modo che le informazioni vengano trasmesse, nel messaggio info.
Ora, vedremo come questo è utile per noi quando guardiamo il lato cliente un
po 'più tardi.
Quindi, in questa situazione,
gestiremo questo come segue.
E non solo, quando chiamiamo questo passaporto autenticare,
abbiamo anche bisogno di passare in un (req, res,
next) come quella striscia di tre parametri.
Quindi questa è la struttura.
Quando hai bisogno di chiamare l'autenticazione del passaporto,
aspettati che ti trasmetta informazioni come questa come metodo di richiamo qui.
Quindi è anche necessario fornire questo req, res prossimo anche lì.
Ora, se questo dovesse accadere.
Quindi diremo se (err).
Quindi, se si verifica un errore,
diremo ritorno successivo (err) e quindi lasciare che il
gestore degli errori del nostro router espresso si occupi di questo.
Ora, prenderemo in considerazione altre situazioni.
Se (! ), quindi se abbiamo raggiunto questo punto significa che
non è stato un errore che si è verificato, ma invece forse l'utente non è stato trovato.
Se l'utente non viene trovato, l'utente qui verrà impostato su null in questo caso.
Quindi, in quella situazione se l'utente non esiste,
allora dobbiamo essere in grado di passare le informazioni sul lato server.
Quindi quello che faremo è passeremo in queste informazioni in questo formato,
quindi ho intenzione di tagliare questo fuori da qui, e
poi incollarlo qui e poi modificheremo così.
Se l'utente è nullo, allora invieremo indietro uno StatusCode
di 401 che significa non autorizzato, e
poi invieremo indietro informazioni di successo, falso.
E poi non passeremo indietro il token, passeremo indietro il messaggio di stato.
Quindi qui diremo login, Non riuscito.
E poi la terza informazione passerà queste informazioni,
quell'oggetto che abbiamo ricevuto qui come terza parte in
quel messaggio di risposta che inviamo indietro dal nostro server qui.
Quindi il flag di successo verrà ripristinato su false.
Lo stato verrà impostato Accesso non riuscito e le informazioni di errore,
che viene passato nelle informazioni verranno restituite.
Ora si noti che questa situazione si verificherà se il nome utente e
la password non sono corretti.
E quindi questo non è un errore, nel senso di errore, ma il fatto che l'autenticazione
non sia riuscita a trovare l'utente o la password dell'utente non è corretto.
In modo che le informazioni vengano codificate nell'afflusso che arriva, e in modo
che io possa tornare come errore al mio lato client.
Altrimenti parte viene
gestita come REQ.login.
Quindi, se questo ha successo,
passport.authenticate aggiungerà questo metodo chiamato REQ.login all'utente.
Quindi a questo punto passeremo solo l'oggetto utente che abbiamo ottenuto.
Quindi qui, se abbiamo raggiunto questo punto,
allora ciò significa che l'oggetto utente non è nullo e
anche nessun errore si è verificato, quindi ciò significa che
l'utente può essere loggato e quindi diremo err.
Quindi cercherà di accedere all'utente.
Quindi diremo se err.
E poi passeremo indietro lo stesso tipo di informazioni di errore che abbiamo fatto qui.
Quindi, in questo caso, se l'errore.
In caso di errore, allora passeremo indietro il codice di stato 401 e
diremo che il successo è falso e lo stato è Login Unsuccessed.
E poi le informazioni di errore
passeremo questo come invece di
informazioni passeremo in non poteva accedere utente.
Quindi questo è il messaggio che passerà qui, se si verifica l'errore.
Altrimenti, saremmo qui sotto.
E così a questo punto saremmo in grado di generare il token.
Quindi, se abbiamo raggiunto fino a questo punto, significa che l'utente ha
effettuato correttamente l'accesso e quindi ora possiamo generare il token.
Quindi genereremo il token in base all'ID utente e
poi passeremo indietro quel token all'utente.
Quindi qui diremo token var.
E poi possiamo dire res.statusCode = 200, e quindi res.json (successo) è vero, il
che significa che l'utente ha effettuato correttamente l'accesso.
E così lo stato sarebbe Login riuscito, e
quindi la terza parte invece dell'errore passerò il token all'utente.
Quindi diremo token, token,
questo token che abbiamo appena ottenuto in precedenza, in modo che al token venga passato
come proprietà token del messaggio di luce rip.
Quindi qui, si noti che questo asse è impostato su true.
Quindi, il che significa che l'utente ha effettuato correttamente l'accesso.
E così l'utente può procedere in avanti a questo punto.
E questo deve essere fatto all'interno del REQ.login qui.
Quindi a questo punto chiuderemo il REQ.login.
Quindi nota che questo è all'interno di questo REQ.Login qui.
Quindi lì dentro passeremo questi tre indietro.
Quindi lasciatemi solo indent trese tre righe in.
E così è così che gestiremmo il login degli utenti.
Quindi di nuovo, rivedere questo codice ancora una volta.
Quindi faremo post router, ma
invece di fare l'autenticazione passaporto proprio lì, diremo req, res,
prossimo e poi dentro qui faremo un passport.authenticate per il locale.
E questo autenticazione passerà indietro, quindi possiamo fornire una funzione di callback a quello.
E questa funzione di callback restituirà l'errore, l'utente o
le informazioni qui.
E quindi, se fa un errore, permetteremo solo al gestore di errori espresso
di occuparsi di questo.
Se l'utente è nullo, significa che l'accesso dell'utente non è riuscito
e il motivo sarà nelle informazioni in modo che verrà restituito come
errore di informazioni nel messaggio del piano qui.
Se arriviamo a questo punto, l'utente viene verificato con successo.
Quindi effettueremo il login all'utente.
Quindi il passport.authenticate aggiungerà questo metodo chiamato Login
al messaggio di richiesta, in modo da poter chiamare il login con l'utente e
se questo restituisce un errore, allora restituiremo l'errore qui in modo appropriato.
In caso contrario, avremmo raggiunto il punto in cui l'utente è stato
autenticato correttamente in modo che possano generare il token Web JSON qui e restituire il
token Web JSON all'utente per confermare che l'utente è stato registrato correttamente.
Quindi questo è l'insieme di passi che useremo qui.
Ora il motivo per cui faccio un modo più elaborato di gestirlo è che voglio
distinguere tra la situazione in cui si verifica un errore genuino durante
il processo di applicazione, in contrasto con la situazione in cui il nome utente non è valido
o la password non è valida.
Quindi questi due casi saranno gestiti da questa situazione in cui le informazioni
porteranno le informazioni a noi.
Quindi non è un errore perse, ma questa è una situazione in cui
l'utente non è un utente valido o la password dell'utente non è valida.
Quindi è così che gestiranno il processo di accesso dell'utente.
Inoltre, aggiungerò un altro metodo qui chiamato,
checkJwToken.
È del tutto possibile che mentre il client ha effettuato l'accesso e
ottenuto il token Web JSON, in un secondo momento, il token Web JSON potrebbe scadere.
Quindi, se l'utente tenta di accedere dal lato client con un token scaduto
al server, il server non sarà in grado di autenticare l'utente.
Quindi a intervalli periodici potremmo desiderare di controllare incrociando per assicurarci che il
token web JSON sia ancora valido.
Quindi questo è il motivo per cui sto includendo un altro endpoint chiamato
CheckJWttoken, quindi se fai un get a checkJWttoken.
Includendo il token nell'intestazione di autorizzazione,
questa chiamata restituirà un true o false per indicare
se il token web JSON è ancora valido o meno.
Se non è valido, il lato client può avviare un altro login per Per
l'utente ottenere un nuovo token Web JSON, se necessario.
Quindi per fare questo, diremo cors, corsWithOptions e,
req, res, qui, come previsto.
E qui diremo,
passport.authenticate ('jwt',
E, {session: false}).
E questo restituirebbe err, utente, informazioni.
Quindi ricordate come abbiamo usato l'autenticatore Passport prima.
Quindi la sessione JWT cade qui.
Quindi prima qui diciamo, passport.authenticate locale.
Quindi questo è per l'autenticazione locale.
Quindi questo è per l'autenticazione del token web JSON.
Quindi, quando lo chiamiamo, quindi, dal momento che questo sta per verificare il token web JSON,
quindi ho intenzione di dire, se (err), tornare next (err).
E poi lascia che il gestore degli errori Express si occupi di quella situazione.
E poi diremo, se (! ),
Se l'utente non esiste, allo stesso modo, altrimenti.
Quindi, il che significa che se l'oggetto utente è stato trovato dal token web JSON e
quindi caricato su req.user, significa che l'utente è un utente valido.
E così può essere permesso di procedere avanti.
Altrimenti, diremo che l'utente non esiste.
Quindi dobbiamo dedurre che il token web JSON è scaduto.
Quindi, a questo punto, invieremo una riserva con il codice di stato,
401, quindi non autorizzato.
SetHeader (, 'Content-Type',
'application/json').
E poi restituiremo res,
.json, diremo, {status:,
'JWT non valido! '.
E poi restituiremo una bandiera chiamata successo: falso.
E poi, Restituiremo le informazioni che
otteniamo se l'utente non è autenticato come l'errore a questo punto.
In caso contrario, ciò significa che raggiungiamo questo punto quando l'utente è un utente valido.
Quindi, in questo caso, lasciami copiare quel codice qui,
invieremo un codice di stato di 200, e
quindi il res.json invierà JWT,
valido! , e il successo sarà vero.
E la terza parte, invieremo le informazioni dell'utente. In
questo modo, quando questo endpoint viene chiamato
con il metodo get, questo verificherà se il token è valido o meno.
Se il token è valido, riceverai questa risposta.
E dal flag di successo nella risposta,
puoi verificare se il token web JSON è valido o meno.
E questo è utile sul lato client.
Ora questo passaporto qui, passport.authenticate qui,
dovrà essere fornito con req e res come i due parametri qui.
Quindi è così che chiamiamo quel passport.authenticate.
Si noti che ogni volta che si chiama passport.authenticate e
si aspetta questa funzione di callback qui, è necessario aggiungere questo punto, req,
.res, a quel passport.authenticate, e poi di nuovo qui.
Quindi con questo, abbiamo aggiornato tutto sul lato server.
Quindi salviamo tutte le modifiche sul lato server.
Quindi ora il nostro server è pronto a
gestire le richieste in arrivo dal nostro client Angular.
Con questo, completiamo questo esercizio.
In questo esercizio, abbiamo ora preparato il nostro server Express per
gestire le richieste in arrivo dal nostro client Angular.
Nel prossimo esercizio, vedremo il client Angular in modo più dettagliato per
capire come sta comunicando con questo server aggiuntivo.
Questo è un buon momento per fare un commit Git con il messaggio,
integrando client e server.
[ MUSIC]