‫Jonas: Ora continuiamo a scrivere la
‫nostra funzione middleware di protezione.
‫Quindi, nell'ultima lezione, abbiamo letto il
‫token dall'intestazione di autorizzazione e
‫quindi abbiamo verificato se il token esiste effettivamente.
‫Quindi proprio qui.
‫E poi, abbiamo il passaggio di verifica per il token.
‫E spero che tu ricordi che
‫in questo passaggio verifichiamo se qualcuno ha manipolato
‫i dati o anche se il token è già scaduto.
‫Quindi abbiamo già usato, dal pacchetto token web JSON, la funzione di
‫assegnazione della funzione,
‫e ora useremo la funzione di verifica.
‫Quindi, proprio come prima, jwt. verifica, e poi
‫lì dentro, come puoi immaginare, passiamo il token in modo che
‫l'algoritmo possa leggere il payload e quindi
‫ricordare che anche questo passaggio ha bisogno del segreto.
‫Quindi, in pratica, per creare la firma di prova.
‫Quindi quel segreto è il processo. avv. JWT_SECRET.
‫Ricordati che?
‫Ora, come terzo
‫argomento, questa funzione richiede effettivamente una funzione di callback.
‫Quindi questa richiamata verrà eseguita
‫non appena la verifica sarà stata completata.
‫Quindi vedi che questa verifica
‫qui è in realtà una funzione asincrona.
‫Quindi verificherà un token e poi,
‫al termine,
‫chiamerà la funzione di callback che possiamo specificare.
‫Ora, abbiamo lavorato con le promesse tutto
‫il tempo, e non voglio davvero rompere questo schema qui.
‫E così, in realtà promettiamo questa funzione.
‫Quindi, in sostanza, per farlo tornare una promessa.
‫In questo modo, possiamo quindi utilizzare async
‫wait proprio come qualsiasi altra funzione asincrona che abbiamo utilizzato.
‫Quindi, per fare
‫ciò, Node ha effettivamente una funzione di promessa incorporata.
‫Tutto quello che dobbiamo fare per
‫usarlo è richiedere il modulo util integrato.
‫Quindi facciamolo proprio in cima, in realtà.
‫In questo modo verrà creato un oggetto chiamato util, require...
‫Va bene, quindi sta per utilità.
‫Non è quello che volevo.
‫Quindi sta per utilità.
‫E poi là, useremo il metodo promisify.
‫Ma dal momento che useremo solo quell'unico metodo,
‫possiamo effettivamente farlo più facilmente.
‫Quindi, invece
‫di farlo, possiamo semplicemente destrutturare quell'oggetto e prendere
‫la promessa direttamente da lì.
‫Quindi, di nuovo, si tratta solo di utilizzare la destrutturazione ES6.
‫Ok, così e ora è molto facile da usare.
‫Tutto ciò che dobbiamo fare è effettivamente chiamare promisify.
‫Quindi prometti e poi passa la funzione lì dentro.
‫E così ora, tutto questo qui è una
‫funzione che
‫dobbiamo chiamare, che poi restituirà una promessa.
‫Quindi qui, chiamiamo effettivamente la funzione.
‫E questo restituirà quindi una
‫promessa, quindi possiamo aspettarla e memorizzare il risultato in una variabile.
‫Quindi quel valore del risultato della
‫promessa sarà effettivamente i dati
‫decodificati, quindi il payload decodificato da questo token Web JSON.
‫Quindi lascia che lo chiami decodificato qui.
‫Va bene.
‫E possiamo aspettare perché in realtà abbiamo già detto
‫che è una funzione asincrona.
‫E ora, solo per vedere che
‫funziona davvero, registriamo anche questi dati decodificati sulla console.
‫E in realtà, possiamo rimuovere questa console. disconnettere il token.
‫Quello di cui non abbiamo più bisogno.
‫Quindi proviamo a inviare di nuovo questa richiesta, e sì, ma
‫questa volta attivando effettivamente questa intestazione di
‫autorizzazione in modo da inviare un token Web JSON insieme alla richiesta.
‫Quindi questo l'ha mandato.
‫E ora, in effetti, abbiamo accesso
‫ai dati, quindi ora abbiamo accesso al percorso protetto.
‫Va bene?
‫Ma quello che volevo vedere è questo oggetto decodificato qui.
‫E quindi questo qui dovrebbe essere l'ID utente.
‫Quindi diamo un'occhiata di nuovo a Postman.
‫Quindi 62a42.
‫E quindi, in effetti, bene, dove lo abbiamo?
‫Diamo un'occhiata a Compass.
‫E infatti, l'ID di questo utente è questo 62a42.
‫E quindi questo significa che qui abbiamo
‫effettivamente il nostro carico utile corretto.
‫Quindi, in pratica, l'ID utente corretto.
‫Abbiamo poi anche il timestamp della data di
‫creazione e della data di scadenza del token.
‫Quindi questo funziona.
‫Ma ora proviamo effettivamente a manipolare il payload di
‫questo token.
‫Quindi copiamolo di nuovo qui.
‫Ma poi vado al debugger JWT.
‫Quindi di nuovo, a jwt. io.
‫Quindi portiamolo via.
‫E ora quello che farò è cambiare alcuni
‫dati qui e questo cambierà il token codificato qui, che posso
‫quindi andare avanti e copiare.
‫Quindi sostituiamo semplicemente, in
‫realtà, sostituirò questi due numeri qui con
‫qualcosa di diverso.
‫E così, come vedi, questo ha cambiato il token qui.
‫E così ora, proverò effettivamente ad
‫accedere a quel
‫percorso protetto usando questo token web JSON manipolato.
‫Ok, ha senso?
‫Quindi solo per vedere se funziona correttamente.
‫Quindi sto copiando
‫questo qui ora e incollando quest'altro diverso.
‫Quindi, se ora invio questa richiesta, otteniamo un errore.
‫Quindi, fantastico.
‫Quindi, vediamo che il nome dell'errore è JsonWebTokenError
‫e abbiamo una firma non valida.
‫Quindi, fantastico.
‫È esattamente quello che stavamo cercando.
‫Quindi questo è uno dei due errori che possono verificarsi.
‫L'altro è che il token è già scaduto.
‫Quindi questo si chiama JsonWebTokenError e
‫quindi, in realtà, andiamo avanti e gestiamo questo errore ora.
‫E il modo
‫in cui potremmo farlo è aggiungere un blocco try-catch proprio qui.
‫Destra?
‫Quindi, subito dopo aver eseguito questo
‫codice, potremmo introdurre un
‫blocco try e quindi nel catch creeremmo errori
‫che sarebbero stati inviati al client.
‫Ora, invece di farlo in
‫questo modo, in realtà voglio usare il nostro middleware di
‫gestione degli errori globale per farlo per noi.
‫Quindi non ci piace gestire gli errori proprio qui
‫nella nostra funzione middleware.
‫Invece, di solito lo deleghiamo al controller degli errori.
‫E quindi, facciamo la stessa identica cosa qui.
‫Quindi controller di errore.
‫E poi è esattamente la stessa
‫cosa che abbiamo con i nostri altri errori qui.
‫Quindi, ad esempio, l'errore di convalida proviene da Mongoose,
‫quindi da un'altra libreria.
‫E ora, questo errore proviene in realtà da un'altra
‫libreria e ha anche il suo nome.
‫Quindi prendiamolo.
‫Ed è JsonWebTokenError.
‫Va bene.
‫E così, facciamo molto simile qui.
‫Quindi se. name
‫è questo, allora l'errore dovrebbe essere uguale a gestire l'errore.
‫Va bene.
‫Quindi andiamo avanti
‫e creiamo questa funzione, in realtà, da qualche parte quassù.
‫E questo è in realtà estremamente semplice.
‫Tutto ciò che fa è accettare un errore
‫e quindi restituire un nuovo AppError.
‫Va bene?
‫Quindi in
‫questa funzione freccia ES6, come spero tu sappia, possiamo scrivere queste righe
‫in cui non dobbiamo nemmeno specificare
‫le parentesi graffe e nemmeno la parola chiave return.
‫Quindi questo restituirà automaticamente
‫e implicitamente tutto ciò che abbiamo inserito qui.
‫Destra?
‫Quindi, quello
‫che vogliamo dire qui è semplicemente, token non valido, per
‫favore accedi di nuovo.
‫E poi, il codice di errore, proprio come prima,
‫è un 401 per Non autorizzato.
‫Ora, questo funziona solo, ricorda, in produzione.
‫E quindi, se lo facessimo di nuovo ora,
‫otterremmo esattamente la stessa cosa.
‫E quindi, torniamo qui ed eseguiamo
‫questo in produzione.
‫Quindi npm run start:production.
‫Sì, proprio così.
‫Quindi, se proviamo di
‫nuovo ora, vediamo se otteniamo il nostro errore.
‫E infatti, lo facciamo.
‫Quindi se, in questo momento, un utente in produzione
‫tenta di accedere alla nostra app con
‫un token non valido, beh, riceve solo questo messaggio di errore.
‫Va bene?
‫Quindi questo è il primo errore che possiamo ottenere.
‫Ma un altro è che l'utente tenta
‫di accedere all'applicazione
‫con un token già scaduto.
‫E quindi, ora proviamo a creare quell'errore.
‫E per farlo, cambierò
‫il tempo necessario alla scadenza del token.
‫Quindi adesso abbiamo 90 giorni.
‫Mettiamolo a tipo cinque secondi.
‫Va bene.
‫Dagli un salvataggio.
‫E ora prova ad accedere di nuovo.
‫Quindi salviamo anche questo qui.
‫Quindi, negli utenti, quindi accedi.
‫Quindi possiamo accedere e quindi ci darà un nuovo token,
‫ma questo token è valido solo per cinque secondi.
‫E così, questi cinque secondi dovrebbero essere passati a questo punto.
‫Quindi ora copierò questo token e proverò ad accedere al
‫nostro percorso protetto utilizzando quel token.
‫Quindi incollalo qui.
‫E ora, vediamo cosa otteniamo.
‫E in effetti, per qualche ragione, ha funzionato.
‫Quindi diamo di nuovo un'occhiata al nostro debugger JWT.
‫E dice, creato il 2 maggio, ma scade
‫solo il 31 luglio.
‫Quindi qualcosa è andato storto nella creazione del token, immagino.
‫E quindi, cambiamo questo di nuovo qui.
‫E ne metterò solo cinque qui.
‫Quindi, quel cinque dovrebbe stare
‫per cinque millisecondi, o posso anche, tipo, mettere
‫5000, che dovrebbe essere cinque secondi.
‫Va bene.
‫Quindi permettetemi di salvarlo di nuovo ora per riavviare il server.
‫Ritenta.
‫Quindi accedi di nuovo qui.
‫Va bene.
‫Quindi ora tutto
‫ciò che dobbiamo fare è sostanzialmente aspettare cinque secondi, e quel tempo dovrebbe essere già passato a questo punto.
‫Incollalo di nuovo qui.
‫E andiamo.
‫E infatti, otteniamo un errore.
‫Ora ricorda come questo è
‫fondamentalmente l'errore standard che otteniamo nel caso in cui non
‫gestiamo correttamente quell'errore nella nostra gestione degli errori.
‫Destra?
‫Quindi diamo un'occhiata all'errore.
‫E in realtà, l'abbiamo qui nella console.
‫Quindi vediamo da dove viene.
‫E sì, viene da questo posto.
‫Quindi questo è il caso in cui abbiamo un errore sconosciuto.
‫Ricorda, quindi un errore che non è contrassegnato
‫come errore operativo e quindi
‫vogliamo registrarlo.
‫Quindi lo registriamo qui e poi
‫inviamo questo messaggio di
‫errore generico al client, quindi quello che abbiamo appena
‫visto in Postman.
‫Ma qui abbiamo effettivamente i dettagli di questo errore.
‫E così, questo ha il nome di TokenExpiredError.
‫Va bene.
‫E quindi, ora gestiamo anche questo.
‫Quindi lo sto copiando ora e poi ne creo
‫solo un altro se qui.
‫Quindi se l'errore. name è uguale a questo, beh
‫allora, diciamo, handleJWTEpiredError
‫con
‫la freccia.
‫Copiamolo e mettiamolo qui.
‫E quindi questo, ovviamente, è molto simile a quello precedente.
‫Il tuo token è scaduto.
‫Per favore esegui l'accesso di nuovo.
‫E ancora, con un codice di errore 401.
‫Ok, proviamo di nuovo.
‫E quindi, questo è esattamente il messaggio di
‫errore che ora dovremmo vedere qui.
‫Va bene.
‫E infatti lo è.
‫Grande.
‫Finiamo il processo qui
‫e avviamolo in modalità dev, ovviamente.
‫Quindi npm
‫inizia, e va bene.
‫Quindi questo non ci serve altro, quindi chiudiamolo.
‫O in realtà, correggiamo questo piccolo errore qui, perché in effetti
‫non usiamo affatto questo errore qui.
‫Quindi liberiamocene.
‫E poi quaggiù, non abbiamo bisogno di passarlo lì dentro.
‫Freddo.
‫Ovviamente, dobbiamo anche riportarlo a 90 giorni.
‫Va bene.
‫E
‫così, giusto per essere davvero sicuri, accediamo di nuovo
‫qui, copiamo il
‫token e mettiamolo qui.
‫Ora, questo processo qui di copiare il
‫token e poi incollarlo qui in questa intestazione può
‫sembrare un po' strano, e in realtà lo
‫sistemeremo in uno
‫dei video futuri in modo
‫che fondamentalmente questo processo avvenga automaticamente.
‫Ma ora, l'importante è che sia effettivamente
‫tornato a funzionare ora.
‫Quindi possiamo effettivamente sbarazzarci di questa console. accedi qui e vai
‫al passaggio successivo.
‫E potremmo davvero fermarci qui ora, se volessimo.
‫E ancora, la maggior parte dei tutorial
‫che scoprirai là, in effetti, si fermerebbe qui.
‫Ma questo non è ancora abbastanza sicuro.
‫Quindi, ad esempio, cosa succede se l'utente
‫è stato cancellato nel frattempo?
‫Quindi il token esisterà ancora, ma se
‫l'utente non esiste più, allora
‫in realtà non vogliamo accedervi, giusto?
‫O ancora peggio, cosa succede se l'utente ha effettivamente cambiato
‫la sua password dopo che il
‫token è stato emesso?
‫Bene, anche questo non dovrebbe funzionare, giusto?
‫Ad esempio, immagina che qualcuno
‫abbia rubato il token Web JSON da un utente.
‫Ma poi, per
‫proteggersi da ciò, l'utente cambia la sua password.
‫E quindi, ovviamente, quel vecchio token emesso prima
‫della modifica della password non dovrebbe più essere valido.
‫Quindi non dovrebbe essere accettato di accedere a percorsi protetti.
‫E quindi, questo è il tipo di cose che implementeremo
‫qui nei passaggi tre e quattro.
‫Quindi la prima cosa da fare è verificare se
‫l'utente esiste ancora.
‫E così, quello dovrebbe essere il più facile.
‫Quindi diciamo solo, Utente. trova per ID.
‫E quindi, questo è il motivo
‫per cui abbiamo effettivamente
‫l'ID nel payload, perché ora possiamo usare
‫quell'ID e interrogare l'utente usando solo quell'ID.
‫Così decodificato. ID.
‫Va bene?
‫Quindi dovrebbe quindi trovare il nuovo utente.
‫E, naturalmente, dobbiamo aspettarlo e quindi
‫memorizzarlo in una variabile.
‫Lo chiamo il freshUser.
‫Va bene?
‫Perché non è davvero un nuovo utente.
‫Questo è solo quando ne creiamo uno.
‫Ma questo non è davvero nuovo, è
‫solo l'utente basato sull'ID decodificato.
‫Va bene?
‫E possiamo
‫farlo in modo da essere sicuri al 100% che l'ID
‫sia effettivamente corretto, perché se lo abbiamo
‫fatto fino a questo punto del codice qui, significa che il processo
‫di verifica che abbiamo precedentemente, qui, ha avuto successo.
‫In caso contrario, ciò avrebbe causato un errore
‫che avrebbe poi impedito il
‫proseguimento della funzione.
‫E quindi, di nuovo,
‫questo processo di verifica qui è responsabile della verifica
‫se nessuno ha alterato l'ID che
‫si trova nel payload di questo token.
‫E quindi, per questo motivo,
‫possiamo essere sicuri al 100% che l'utente per il quale
‫abbiamo emesso il JWT è esattamente quello il cui ID è
‫ora all'interno del payload decodificato, quindi questo.
‫Va bene?
‫Quindi il processo di verifica è davvero fondamentale.
‫È davvero ciò che fa funzionare tutto questo.
‫Ad ogni modo, ora ciò che dobbiamo fare è
‫verificare se esiste effettivamente un freshUser.
‫E se no, allora, ovviamente, restituiremo
‫un nuovo errore.
‫Quindi, se non c'è freshUser,
‫torna da questo middleware e chiama quello
‫successivo con un errore.
‫Quindi questo è uno schema che abbiamo
‫visto più e più volte a questo punto, giusto?
‫Quindi il token non esiste
‫più.
‫E in effetti è il contrario.
‫Quindi, in realtà, l'utente
‫appartenente al token non esiste più.
‫Destra?
‫E poi il 401.
‫Va bene.
‫Quindi testiamolo ancora una volta.
‫E creiamo effettivamente un nuovo utente per quello.
‫Quindi prova solo con la stessa password, quindi usiamo sempre
‫la stessa qui solo per rendere il nostro
‫test un po' più semplice.
‫E so che tutti questi test qui
‫fanno impiegare molto tempo al
‫video, ma ovviamente è molto importante testare tutto ciò che
‫facciamo, specialmente in
‫un argomento così importante come l'autenticazione.
‫Quindi ora sto usando questo JWT qui, quindi
‫lo incollo qui, ma ovviamente, prima di inviare la richiesta,
‫andrò avanti ed eliminerò immediatamente quell'utente.
‫Va bene?
‫Quindi, di nuovo, supponiamo che
‫qualcuno abbia creato un utente e poi abbia effettuato l'accesso,
‫e diciamo che, dopo un po' di tempo, l'utente è stato eliminato.
‫Ma nel frattempo, qualcuno potrebbe aver avuto accesso a quel
‫JWT
‫e ora potrebbe provare ad accedere come quell'utente
‫che è stato, in effetti, già eliminato.
‫E quindi, ancora una volta, non dovremmo permettere che ciò accada.
‫Quindi permettetemi di eliminare questo utente qui ora.
‫E ci siamo.
‫E quindi, proviamolo ora.
‫E ancora, tieni presente che l'utente
‫appartenente all'ID che è in questo payload ora non è più lì.
‫Quindi vediamo.
‫E infatti, riceviamo questo messaggio di errore che abbiamo appena creato.
‫Quindi anche quello funziona.
‫E andiamo all'ultimo.
‫Quindi, passaggio numero quattro, controlla se l'utente ha
‫modificato di recente la password.
‫Quindi, in pratica, dopo l'emissione del token.
‫E per implementare questo test, creeremo effettivamente un altro
‫metodo di istanza.
‫Quindi, in pratica, un metodo
‫che sarà disponibile su tutti i documenti.
‫Quindi i documenti sono istanze di un modello.
‫Va bene?
‫E lo facciamo perché
‫è un bel po' di codice di cui abbiamo bisogno per questa verifica.
‫E quindi, in realtà, questo
‫codice appartiene al modello Utente e non proprio al controller.
‫Va bene?
‫E quindi,
‫facciamolo come abbiamo fatto prima per controllare la password.
‫Quindi nel modello utente, abbiamo già
‫implementato questo metodo di istanza statica CorrectPassword, ricordi?
‫E così, ora creiamone un altro.
‫Quindi userSchema. metodi. password modificataDopo.
‫Quindi funzione, e in
‫questa funzione passeremo il timestamp JWT.
‫Quindi, in pratica, quel timestamp che dice quando
‫è stato emesso il token.
‫Quindi chiamiamolo JWTTimestamp.
‫Va bene.
‫E per impostazione predefinita, restituiremo false da questo metodo.
‫E ciò significherà che l'utente non ha cambiato
‫la sua
‫password dopo l'emissione del token.
‫Va bene?
‫Quindi mettiamolo qui, return false, fondamentalmente per impostazione predefinita.
‫Va bene.
‫Ma poi,
‫abbiamo anche if this, e ricordiamo che in un metodo di istanza,
‫la parola chiave this punta sempre al documento corrente.
‫E quindi, qui abbiamo accesso alle proprietà.
‫Ora, abbiamo effettivamente bisogno di creare un campo ora nel nostro schema per
‫la data in cui la password è stata modificata.
‫Quindi non l'abbiamo ancora.
‫Quindi aggiungiamolo rapidamente qui.
‫Quindi passwordChangedAt e il tipo
‫sarà un Date.
‫Ora, questa proprietà passwordChangedAt qui
‫verrà sempre modificata, ovviamente, quando qualcuno
‫cambia la password.
‫Quindi in questo momento, non abbiamo quella logica da nessuna parte, e
‫quindi da nessuna parte stiamo effettivamente definendo questa proprietà.
‫E così, la maggior parte dei documenti, quindi
‫la maggior parte degli utenti, semplicemente non avranno questa
‫proprietà nei loro dati, quindi nel loro oggetto, giusto?
‫E quindi, ovviamente, dobbiamo testarlo.
‫Va bene?
‫Quindi, se la
‫proprietà passwordChangedAt esiste, solo allora vogliamo fare effettivamente il confronto.
‫Va bene?
‫Ma se
‫no, quindi se passwordChanged non esiste, allora significa che l'utente non
‫ha mai effettivamente cambiato la
‫password, e quindi possiamo semplicemente restituire false.
‫Quindi, di nuovo, questa è la nostra impostazione predefinita,
‫il che significa che l'utente non
‫ha cambiato la password dopo questo timestamp.
‫Va bene.
‫E
‫ora, solo per iniziare, accediamo effettivamente alla console. passwordChangedAt e, naturalmente, anche JWTTimestamp, solo così
‫possiamo
‫vedere come possiamo confrontarli.
‫Va bene.
‫E ora dobbiamo
‫creare effettivamente un utente che abbia questa proprietà, ok?
‫E ancora, più avanti nella sezione quando implementeremo
‫la logica per
‫cambiare la password è quando imposteremo questa proprietà.
‫Va bene?
‫Ma ora
‫lo imposteremo artificialmente, fondamentalmente, qui quando creiamo un nuovo utente.
‫Va bene?
‫Quindi mettiamolo qui.
‫E qui, qualsiasi data, in realtà, servirà.
‫Quindi diciamo il 30 aprile 2019 qui.
‫E quindi dovrebbe essere analizzato bene in MongoDB.
‫Proviamo, vediamo se funziona.
‫E questo non ha funzionato.
‫Quindi non potrebbe davvero analizzare la data, diciamo.
‫E in realtà, devo iniziare con l'anno e
‫poi il giorno alla fine.
‫Quindi il 2019 e poi il 30 aprile.
‫Riprova.
‫E così vedi che ora funziona davvero.
‫Quindi abbiamo questa data analizzata qui.
‫Va bene?
‫Ora, per vedere effettivamente
‫il risultato di ciò, dobbiamo ovviamente chiamare questo metodo.
‫Va bene?
‫Quindi è quello che faremo qui al punto quattro.
‫Va bene?
‫E quindi, ricorda
‫che possiamo chiamare questo metodo di istanza su un documento utente.
‫Così frescoUtente. changePasswordAfter, e poi
‫quel timestamp.
‫Quindi questo è decodificato. iat, così emesso a, fondamentalmente.
‫Va bene.
‫Quindi vediamo semplicemente il risultato di farlo.
‫E quindi, ovviamente, questo dovrebbe ora, non
‫qui, quindi ora dovrebbe registrare nella console questi due valori.
‫Va bene.
‫Ora, ovviamente,
‫ho bisogno di accedere esattamente con questo utente, quindi con
‫test, quindi eccoci qui.
‫Accesso.
‫Copia di nuovo questo token qui.
‫E ancora, fondamentalmente lo
‫automatizzeremo nel prossimo video, in realtà.
‫Va bene.
‫Incollalo qui.
‫E ora, abbiamo effettivamente questo bug qui.
‫Quindi ho appena scritto male questo nome di funzione qui.
‫Bene, copiamolo e basta.
‫Ritenta.
‫Oddio.
‫Cosa c'è che non va adesso?
‫E vedo che ho semplicemente dimenticato questo registro qui.
‫Quindi un altro stupido errore.
‫Probabilmente l'ha visto arrivare.
‫Ma ora ci siamo.
‫Quindi tutto ha
‫funzionato bene e tutto ciò che
‫volevamo davvero vedere per ora erano questi due risultati.
‫Quindi fondamentalmente abbiamo questo qui con questo
‫formato di data, e poi l'altro in questo millisecondo o secondo
‫timestamp qui.
‫E quindi, ora dobbiamo convertire questa
‫passwordChangedAt anche in un timestamp del genere.
‫Va bene?
‫E quindi, per questo, creiamo una nuova variabile.
‫Così cambiatoTimestamp.
‫E possiamo usare questo. passwordCambiataAt. prendi tempo.
‫Va bene?
‫E quindi,
‫questa è una delle tante, molte funzioni di data che JavaScript ci offre.
‫Va bene.
‫E ora confrontiamo rapidamente questi
‫due perché non siamo ancora del tutto pronti, in realtà.
‫Quindi l'invio solo per vedere i risultati qui.
‫E quindi quello che vediamo qui fondamentalmente è che
‫questo qui è
‫ora, fondamentalmente, in secondi, e questo in millisecondi.
‫Quindi è 1000 volte di più.
‫E quindi, sappiamo che dobbiamo dividerlo per
‫1000 e poi analizzare l'intera cosa come un numero intero.
‫E per questo, usiamo parseInt.
‫Quindi un'altra funzione JavaScript disponibile per i numeri.
‫E poi in realtà dobbiamo anche specificare la base.
‫Quindi questo è un numero in base 10.
‫Va bene?
‫E così ora, vediamo di nuovo il risultato.
‫E ora, sembra molto più amichevole.
‫Va bene.
‫E così, ora restituiamo effettivamente il nostro risultato.
‫E ancora, tieni presente che falso significa non cambiato.
‫Va bene?
‫E non
‫modificato significa sostanzialmente che il giorno o l'ora in cui è stato emesso il
‫token è inferiore al timestamp modificato.
‫Va bene?
‫Quindi, solo per fare un esempio
‫qui, supponiamo che il token sia stato emesso al momento 100.
‫Ma poi, abbiamo cambiato la password, diciamo, al tempo 200.
‫Va bene?
‫E così, abbiamo
‫cambiato la password dopo che il
‫token è stato emesso, e quindi, questo è ora vero.
‫Va bene?
‫Ed è proprio quello che vogliamo
‫restituire qui, perché falso
‫significa non cambiato, e quindi vero, ovviamente, significa cambiato.
‫E quindi, è esattamente quello che abbiamo qui.
‫Ma ora, diciamo che la password è
‫stata modificata l'ultima
‫volta a 200, ma solo dopo
‫abbiamo emesso il token, quindi diciamo, all'ora 300.
‫E quindi, 300, meno di 200?
‫No, è falso.
‫E così, torniamo false, che di nuovo significa non cambiato.
‫E quindi, ecco perché usiamo questo segno meno qui.
‫Va bene?
‫Torniamo al nostro controller e usiamo effettivamente questo.
‫Quindi, se la password è stata effettivamente modificata, beh,
‫in questo caso, vogliamo effettivamente un errore.
‫Quindi torna dopo, di nuovo, un nuovo AppError.
‫Recentemente...
‫Per favore esegui l'accesso di nuovo.
‫Va bene.
‫E ancora una volta il codice 401.
‫Va bene.
‫Quindi, di nuovo,
‫questo tornerà vero se l'utente ha effettivamente cambiato la password.
‫E quindi, se tutto questo qui è vero,
‫beh, allora proprio in quel caso è quando vogliamo
‫che si verifichi questo errore.
‫Va bene?
‫Quindi questo era in realtà l'ultimo passo.
‫Va bene.
‫Quindi, in pratica, se il codice può arrivare
‫fino alla fine di questo codice qui, solo allora verrà eseguito il prossimo.
‫E poi, con next, andiamo al gestore di
‫route successivo, che significa effettivamente concedere l'accesso
‫a quella route protetta.
‫In realtà mettiamolo qui.
‫Concedere l'accesso al percorso protetto.
‫Va bene?
‫Perché questo è davvero tutto ciò che fa il prossimo.
‫Successivamente ci porta al prossimo
‫middleware, che di solito è, quindi, il gestore di route
‫stesso, quindi quello che restituisce i dati che sono stati protetti.
‫Va bene.
‫Solo un'ultima cosa
‫che vogliamo fare qui è effettivamente inserire tutti i dati dell'utente nella richiesta.
‫Quindi possiamo semplicemente dire, req, quindi request, . user sarà uguale a
‫freshUser.
‫Va bene.
‫E ancora, ovviamente,
‫il codice raggiunge questo
‫punto solo qui nel caso in cui tutto sia corretto.
‫Va bene?
‫E quindi,
‫questo qui potrebbe essere utile in futuro.
‫Grande.
‫Proviamolo ancora una volta.
‫E fondamentalmente, questo cambiamento è nel passato ora.
‫E quindi, questo token che abbiamo qui, o in realtà,
‫avrei potuto riutilizzare
‫solo questo invece di registrarlo di nuovo.
‫Ma comunque, questo token è
‫stato emesso dopo la modifica della password.
‫E quindi, questo token ora dovrebbe funzionare.
‫Quindi accediamo di nuovo
‫e proviamo con questo token.
‫E infatti, otteniamo l'accesso.
‫Ora, spostati su Compass per cambiare quella data.
‫Va bene.
‫Mettiamolo un mese dopo.
‫E così, sarà davvero
‫in futuro, almeno nel mio futuro quando registrerò questo video.
‫Ovviamente lo farai in un secondo momento.
‫E quindi, per testarlo, per favore mettilo nel tuo futuro.
‫Quindi nel futuro della data in cui stai
‫guardando questo video.
‫Quindi, se ora
‫torno a Postman e accedo di nuovo, ok, quindi se accedo di nuovo ora
‫e provo ad accedere a quel percorso,
‫beh, questo token verrà emesso, in
‫pratica, dopo che la password è stata modificata.
‫O addirittura prima che la password sia stata modificata.
‫Quindi, scusa per questa confusione.
‫Quindi la password è stata cambiata il 30
‫maggio, ma questo token è stato emesso il 2 maggio, e così, prima.
‫Quindi, in pratica, ora è come se l'utente avesse cambiato la
‫password dopo l'emissione del token.
‫E quindi, questa è esattamente la situazione in cui non vogliamo dare
‫accesso al percorso protetto.
‫E quindi, questo dovrebbe ora riflettere quello.
‫E infatti, l'utente ha cambiato la password di
‫recente, per favore accedi di nuovo.
‫Grande.
‫Quindi ora funziona.
‫Quindi il nostro middleware di protezione è ora completamente implementato.
‫Eliminiamo questa console. accedi qui.
‫Non ho più bisogno di quello.
‫E va bene.
‫Quindi ricapitoliamo rapidamente, e questo video
‫è molto lungo, un
‫po' più lungo di quanto mi aspettassi.
‫Ma è davvero
‫importante capire e spiegare come
‫funziona tutto questo e perché è importante.
‫E quindi, lo preferisco piuttosto che fare questo video molto più breve.
‫Certo, potrei semplicemente scrivere il codice, ma poi non capiresti davvero
‫cosa sta succedendo.
‫Quindi questa parte l'abbiamo già capita.
‫Quindi questa parte, credo anche io,
‫quindi è qui che avviene la verifica, quindi
‫in pratica vedendo se il payload del token
‫non è stato manipolato da una terza parte dannosa.
‫Va bene?
‫E poiché
‫raggiungiamo questo codice qui, significa che nessuno ha
‫modificato il token Web JSON e quindi possiamo ottenere un nuovo utente.
‫Quindi, in pratica, possiamo ottenere l'utente
‫corrente, chiamiamolo effettivamente currentUser.
‫Perchè no?
‫Quindi qui, qui e anche qui.
‫Va bene?
‫Quindi possiamo ottenere
‫l'utente corrente da quell'ID che è stato appena decodificato dal payload.
‫Ora, se currentUser non esiste, quindi
‫questo è ciò che stiamo testando
‫qui, beh, in quel caso non vogliamo
‫dare accesso al
‫percorso e invece creiamo questo nuovo errore.
‫Ma se l'utente esiste, beh,
‫allora arriviamo al
‫punto numero quattro, dove controlliamo se è avvenuta una
‫modifica della password dopo l'emissione del token, giusto?
‫E se lo ha fatto, poi di nuovo, creiamo un nuovo errore.
‫E se non lo fa, beh, allora arriviamo
‫fino alla fine
‫della funzione middleware, dove
‫assegniamo l'utente corrente alla richiesta. user in modo da poterlo utilizzare
‫in una prossima funzione middleware.
‫Va bene?
‫Perché ricorda,
‫questo oggetto request, questo è quello che
‫viaggia, sostanzialmente, da middleware a middleware.
‫Quindi, se vogliamo passare i dati
‫da un middleware a quello
‫successivo, possiamo semplicemente inserire alcune cose sull'oggetto della
‫richiesta, e quindi quei dati saranno disponibili in un secondo momento.
‫Va bene.
‫Quindi, questo è tutto.
‫Questo è
‫un algoritmo di protezione del percorso
‫molto sofisticato e molto completo, fondamentalmente, ma penso che sia davvero importante farlo
‫nel miglior modo possibile.
‫Ad ogni modo, sono felice di vedere che sei
‫arrivato alla fine di questo grande video,
‫e ci vediamo nel prossimo.