Articles

Che cos’è un token Web JSON?

Posted by admin
Myplanet

Seguire

il 31 Maggio 2016 · 13 min leggere

“Un JSON Web Token (JWT), si pronuncia ‘butto’, è un compatto URL-cassetta di sicurezza per rappresentare sostiene di essere trasferiti tra le due parti. Le attestazioni in un JWT sono codificate come un oggetto JSON che è firmato digitalmente utilizzando JSON Web Signature (JWS)””,

Prima di entrare in JWTs, diamo un rapido sguardo a come siamo abituati a fare di autenticazione:

HTTP è un protocollo stateless. Ciò significa che non ricorda nulla da una richiesta all’altra. Se si effettua il login per una richiesta, sarete dimenticati, e sarà necessario effettuare nuovamente il login per effettuare un’altra richiesta. Come puoi immaginare, questo può diventare molto fastidioso velocemente.,

La soluzione vecchia scuola è stata quella di creare quella che viene chiamata “sessione”. Una sessione è implementata in due parti:

  1. Un oggetto memorizzato sul server che ricorda se un utente è ancora connesso, un riferimento al suo profilo, ecc.
  2. Un cookie sul lato client che memorizza un qualche tipo di ID che può essere referenziato sul server rispetto all’ID dell’oggetto sessione.,

Cookie di Autenticazione basata su:

Se un utente visita una pagina web (una richiesta) e il server rileva un cookie di sessione, controlla se attualmente si dispone di una sessione memorizzata con l’ID dal cookie, e se l’oggetto è ancora valida (qualunque cosa significhi: non è scaduto, non revocato, non è nella lista nera, ecc).

Se la sessione è ancora valida, risponderà con la pagina web (o i dati) richiesti., Se trova un oggetto di sessione, quell’oggetto può contenere dati in esso e con questo, il server può “ricordare” chi sei e cosa stavi facendo (ad esempio se si tratta di un negozio di e-commerce, quali prodotti hai aggiunto al nostro carrello).

Se la sessione non è valida (o non è stato rilevato alcun cookie di sessione) risponderà con una sorta di messaggio di errore che dice che la richiesta è “non autorizzata”.

In genere è possibile creare nuove sessioni inviando una combinazione nome utente / password a un endpoint specifico da una pagina di accesso., Se il server può corrispondere a un utente con quel nome utente e password, genererà un nuovo oggetto di sessione sul server e imposterà un cookie sul client con l’ID della sessione per eventuali richieste future.

Se un utente spegne il proprio computer e torna al sito web qualche tempo in futuro, può accedere automaticamente di nuovo (se c’è ancora un cookie nel browser che non è scaduto) o accedere nuovamente attraverso la pagina di accesso. Una volta effettuato l’accesso, la sessione dell’utente può essere recuperata nuovamente dai dati memorizzati sul server e l’utente può continuare con la propria attività (ad es., continuare a fare acquisti dopo aver ricaricato il carrello).

Questo tipo di configurazione ha funzionato abbastanza bene per noi da quando è uscito il web e da quando abbiamo visitato siti web che fanno la maggior parte del loro “pensiero” sul lato server. In genere, si è trattato di una conversazione tra il browser front-end dell’utente e un server back-end corrispondente in una relazione one-to-one.,

Questa configurazione funziona ancora, ma in questi giorni ci sono molte situazioni diverse che richiedono configurazioni diverse (ad esempio, più mobile app nativa a fianco di grandi dimensioni di una singola pagina web apps di contattare più servizi di backend, che può essere niente di più che i dati json senza una pagina web a tutti)., In questi tipi di scenari, il cookie che si ottiene da un server, non corrisponderà — o addirittura verrà inviato — a un altro server (per non parlare dei problemi che vengono creati con CORS).

  • Più di Backend: Che cosa se la vostra applicazione ha bisogno di parlare a un database di backend come immagine separata di elaborazione di back-end?, Di più e di più, il nostro mondo digitale è in fase di dividere, separare micro-servizi; quando l’autenticazione con più di un backend, le cose possono complicarsi (ad esempio, si potrebbe inoltrare tutte le richieste attraverso una centrale app server, che avrebbe poi bisogno di sapere tutta la logica di ogni servizio secondario, o ogni servizio potrebbe implementare complesso inter-comunicazione con il server (e CORS) per verificare in ingresso l’Id di sessione con una centrale auth server… in entrambi i casi il carico sul server app è richiesto e più complesse interconnessioni devono essere mantenuti).,
  • Sessioni: devono essere memorizzate da qualche parte, in memoria, in un database o in un archivio keyvalue come Redis; e devono essere gestiti in modo che vengano rimossi quando scadono o vengono altrimenti invalidati.
  • Scarsa scalabilità: l’archivio di sessione deve essere scalato quando si ridimensiona il server. Il negozio utilizza risorse e aggiunge complessità.
  • Problemi di prestazioni: quando la sessione deve essere memorizzata sul server, è necessario che molte ricerche di database/store si verifichino su ogni richiesta che può impantanare il server.,
  • App native (o app non browser): i browser gestiscono i cookie, ma le app personalizzate non lo fanno (almeno non facilmente), quindi è necessario un diverso tipo di meccanismo di sessione.
  • CSRF: Se vengono utilizzati cookie, è necessaria una maggiore sicurezza per prevenire attacchi cross-site request forgergy poiché il cookie verrà automaticamente inviato al server con qualsiasi richiesta fatta da quel sito.
  • CORS: I cookie + CORS non funzionano bene su domini diversi (in realtà, il vero cross-domain non funziona affatto).,

I token Web JSON sono migliori

I JWT non usano sessioni, non hanno problemi con le app native e in realtà non hanno nemmeno bisogno di speciali protezioni CSRF e funzionano come un incantesimo con CORS.

Con JWT ti registri con un app, molto nello stesso modo si farebbe con un vecchio-scuola di applicazione, e si effettua il login con le tue credenziali (ad esempio nome utente/password, o 3rd party OAuth)., Ma invece di creare una sessione e impostare un cookie, il server ti invierà invece un token Web JSON. Ora puoi usare quel token per fare tutto ciò che vuoi fare con il server (che hai l’autorizzazione a fare).

Pensala come una chiave d’albergo: ti registri alla reception e ti danno una di quelle chiavi elettroniche in plastica con cui puoi accedere alla tua stanza, alla piscina e al garage, ma non puoi aprire le stanze di altre persone o entrare nell’ufficio del gestore. E, come una chiave di un hotel, quando il tuo soggiorno è finito, sei semplicemente lasciato con un inutile pezzo di plastica (cioè, il token non fa più nulla dopo che è scaduto).

In un ambiente multi-server, si potrebbe anche immaginare un JWT simile ad un “Festival Pass” come si otterrebbe un film o di un festival di musica., Se un singolo biglietto del cinema ti consente di accedere a un singolo film da cui puoi partire per ottenere popcorn o utilizzare il bagno e tornare, un Pass del Festival ti consentirà di accedere a qualsiasi film dell’intero festival in luoghi diversi in momenti diversi. Allo stesso modo, puoi prendere il tuo JWT generato da un server e usarlo per autenticarti con server completamente diversi su domini diversi, che condividono lo stesso metodo di verifica., Ognuno di questi altri server non ha bisogno di “chiamare casa” per chiedere se il token è ok, perché possono semplicemente fare un rapido calcolo sul token stesso e controllare direttamente la sua firma e il tempo di scadenza senza incorrere in un hit al database o una richiesta di rete aggiuntiva.

Come funziona JWT

Un JWT è autonomo. Quando ne crei uno, ha tutti i pezzi necessari che devi fare le cose che vuoi fare su un server confezionato al suo interno. Ci sono 3 parti principali, separate da un “.,”

  1. intestazione
  2. un payload
  3. firma

L’intestazione contiene normalmente due cose: il tipo di token (come il payload può essere interpretato), e il nome dell’algoritmo utilizzato per creare la firma (ad es., {tip: ‘JWT’, alg: ‘HS256’}). Questo viene codificato in base64.

La firma è un hash dell’intestazione codificata, del payload codificato e di una chiave “segreta” fornita (memorizzata in modo sicuro sul server) utilizzando l’algoritmo definito nell’intestazione.

Alla fine, ottieni una stringa che assomiglia a “xxxxxxxx.aaaa.,zzzzzzz “dove” x “è l’intestazione codificata,” y “è il payload codificato e” z” è la firma crittografata.

L’intestazione e il payload possono essere facilmente decodificati sul front-end o sul back-end per recuperare qualsiasi informazione tu voglia lì (è solo base64). Tienilo a mente perché questi valori sono essenzialmente “pubblici”, quindi non inserire alcuna informazione privata come un numero di carta di credito o una password o qualcosa del genere.

Ogni volta che si effettua una richiesta al server, si invia il token con la richiesta. In genere questo viene fatto nell’intestazione di autorizzazione come “Autorizzazione: Bearer xxxxxx.,aaaa.zzzzz”. Ma potrebbe anche essere passato in un corpo POST o nell’URL stesso come parametro di query. Quando il server vede il token, lo decodifica e confronta la firma con il segreto che ha memorizzato che sarebbe stato utilizzato per generare il token in primo luogo. Se tutto corrisponde, la richiesta è autentica e risponde con i dati, altrimenti restituisce un messaggio di errore.

Ecco un esempio di token reale. È possibile utilizzare questo bel servizio jwt.io per ispezionare facilmente il token se vuoi vedere cosa c’è dentro.,

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vZXhhbXBsZS5v
cmciLCJhdWQiOiJodHRwOi8vZXhhbXBsZS5jb20iLCJpYXQiOjEzNTY5OTk1MjQsIm5iZ
iI6MTM1NzAwMDAwMCwiZXhwIjoxNDA3MDE5NjI5LCJqdGkiOiJpZDEyMzQ1NiIsInR5cC
I6Imh0dHBzOi8vZXhhbXBsZS5jb20vcmVnaXN0ZXIiLCJjdXN0b20tcHJvcGVydHkiOiJ
mb28iLCJuYW1lIjoiUm9iIE1jTGFydHkiLCJpZCI6Nzh9.-3BnaA1XRiKh8e7zy9ZRTET
f8VngoypqrVW98oQnH4w

Il server prende informazioni dal payload del token (ad esempio come un “UserID”) e costruisce la sua risposta di conseguenza. Questo è il modo in cui il server “ricorda” l’utente, perché può utilizzare l’ID che trova per controllare il nome dell’utente e altre informazioni sul profilo rispetto al suo account nel database (o può semplicemente utilizzare quali dati sono nel payload direttamente senza colpire il database). Se all’utente sono stati concessi diritti di accesso speciali, questi possono essere recuperati anche dal token (ad esempio privilegi di amministratore).,

La chiave (gioco di parole) per tutto questo è la stringa “segreta” che viene memorizzata sul server. Questa è un’informazione che solo il server sa che viene utilizzata per creare nuovi token e convalidare quelli esistenti. Poiché il server è l’unica cosa che conosce il segreto, impedisce l’accesso non autorizzato da parte degli aggressori perché sarebbe tecnicamente troppo difficile decifrare una firma catturata o indovinare il segreto per falsificare una firma artificiosa prima della scadenza di un token emesso. Ricorda di non condividere mai il tuo segreto con nessuno e di inviarlo al tuo server su una linea sicura (ad es., utilizzando SSH).

È anche possibile impostare altri server per utilizzare lo stesso segreto in modo che un token creato da un server possa essere utilizzato anche per autenticarsi con un server completamente diverso (da client a server o da server a server)., Impostazioni più avanzate può essere creato utilizzando il JWA JSON (Web Algoritmi) dove una centrale auth server memorizza un singolo segreto e il server di terze parti ricevere una chiave pubblica generata da quel segreto e utilizzare la chiave pubblica per l’autenticazione della richiesta di servizi da auth server quando il server di terze parti viene richiesta (basti dire che ci sono un sacco di modi diversi di impostare le cose; è molto flessibile).

Se un utente malintenzionato tenta di manomettere i dati del payload (ad es., diritti di amministratore), la firma corrispondente non corrisponderà (perché la firma è stata generata dai dati originali nel payload) e in quanto tale il token non sarà considerato valido sul server e qualsiasi richiesta fatta con esso verrà negata. L’unico modo per creare un token autentico è con il segreto (che dovrebbe essere solo sul server e mai pubblicato).

Un JWT può anche includere altre informazioni utili nel suo payload, chiamato “claims”. Più importante è una data di scadenza., Se è inclusa una data di scadenza, il token diventerà automaticamente non valido quando tale data è passata.

Reclami JWT standard

Esiste un insieme di proprietà standard che puoi utilizzare nel tuo payload per gestire diversi casi d’uso nella tua app. Reclami come questo possono essere utilizzati per aumentare la sicurezza del sistema per prevenire una serie di diversi tipi di attacchi. Assicurati di controllare cosa è disponibile nella libreria che scegli.,

  • iss: l’emittente del token
  • sub: l’oggetto del token
  • aud: il pubblico del token
  • exp: questo sarà probabilmente il reclamo registrato più spesso utilizzato. Questo definirà la scadenza come un valore NumericDate. La scadenza DEVE essere successiva alla data/ora corrente.
  • nbf: definisce l’ora prima della quale il JWT NON DEVE essere accettato per l’elaborazione
  • iat: l’ora in cui il JWT è stato emesso. Può essere utilizzato per determinare l’età del JWT
  • jti: identificatore univoco per il JWT. Può essere usato per impedire che il JWT venga riprodotto., Questo è utile per un token di utilizzo una tantum.

Esempio payload:

Come invalidare un JWT

La parte più interessante di un JWT è che le sue affermazioni possono includere le sue impostazioni di scadenza e poiché la firma è una funzione dell’hash di queste impostazioni, tutto ciò che il server deve fare è controllare le informazioni di scadenza quando verifica il token e rifiutarlo se è scaduto. Ciò significa che non devi preoccuparti troppo di questo. Dopo aver emesso un token, basta lasciarlo fuori in natura e lasciarlo morire da solo.

Ovviamente non tutte le app possono permettersi di farlo., A volte avere un token valido all’aperto anche per un giorno è potenzialmente troppo lungo (ad esempio, per concedere a un utente l’accesso al proprio account se ha dimenticato la password). A volte potresti voler utilizzare un token solo una volta (ad esempio per un reset della password). Altre volte potresti avere un utente malintenzionato registrato nel tuo sistema che vuoi vietare del tutto in modo che tutti i token che hanno già creato non possano più essere utilizzati per accedere al sistema.

Questi scenari possono essere gestiti (se necessario) attraverso una combinazione di attestazioni JWT e meccanismi lato server., Tieni a mente le seguenti opzioni quando consideri l’invalidazione e la scadenza del token:

  • rimuovi il token dal client
  • mantieni una lista nera del token
  • mantieni i tempi di scadenza brevi

La prima opzione semplicemente “butta fuori” il token e lo lascia scadere da solo.

La seconda opzione è un po ‘ più coinvolta in quanto tiene traccia dei token effettivi memorizzati sul server (ad esempio in un database o in un archivio chiave/valore) e utilizza questo elenco durante la verifica del token per verificare se un token è stato inserito nella lista nera., Questo è un po ‘ l’opposto dei negozi di sessione, ma è ancora più performante perché poiché i token scadono naturalmente, possono semplicemente essere rimossi dalla lista nera. La lista nera è necessaria solo per invalidare un token che non è ancora scaduto.,

Infine, in generale, dovresti comunque mantenere i tempi di scadenza del token brevi (come meno di 24 ore, forse solo 1 o 2 ore) in modo che in uno scenario peggiore, un attaccante abbia meno di un giorno per approfittarne, il che probabilmente non è abbastanza tempo per forzare la crittografia della firma, anche con un super-computer the la giuria è ancora fuori sui computer quantistici.

Vantaggi di JWTs

  • Nessuna sessione da gestire (stateless): il token ha tutto il necessario per identificare gli utenti e il resto dello stato della tua app può essere memorizzato nella memoria locale sul lato client., Non c’è bisogno di un oggetto di sessione memorizzato sul server.
  • Portable / Homogenous: un singolo token può essere utilizzato con più backend, anche su domini diversi.
  • Nessun cookie richiesto: puoi memorizzare il token come vogliamo: in localStorage, indexDB o in qualche negozio nativo (o cookie, se vuoi davvero).
  • Mobile Friendly: lo sviluppo di app native (iOS, Android, Windows 8, ecc.) è difficile e ingombrante con i cookie (devi avere a che fare con i contenitori dei cookie), ma l’adozione di un approccio basato su token semplifica enormemente questo.,
  • Scadenza incorporata: JWT ha attestazioni standard che possono essere impostate nel payload quando viene creato un nuovo token. Non c’è più niente da fare.
  • Non è necessario disconnettersi: basta buttare via il token quando hai finito con esso, scadrà da solo. Di solito si desidera dare una breve scadenza, ma se lo si desidera davvero, è possibile tenere traccia di una “lista nera” di token contrassegnati come “non validi” sul server a cui è possibile aggiungere da un logout esplicito o da un amministratore che contrassegna determinati token come non validi.,
  • Funziona con CORS: un approccio di autenticazione basato su token consente di effettuare chiamate AJAX a qualsiasi server, su qualsiasi dominio perché è possibile utilizzare un’intestazione HTTP per trasmettere le informazioni dell’utente.
  • Leva CDN: puoi servire tutte le risorse per la tua app da un CDN (ad esempio javascript, HTML, immagini, ecc.)
  • Facile da eseguire il debug: i JWT possono essere ispezionati e i loro dati esaminati (mentre le sessioni sono memorizzate sul server e sono molto più difficili da vedere e capire).
  • Disaccoppiato / decentralizzato: il token può essere generato ovunque., L’autenticazione può avvenire sul server delle risorse, o facilmente separato nel proprio server, o “auto-emesso”, o altrimenti essere completamente esternalizzato.
  • CSRF Non ha importanza: perché se non hai un token, non puoi fare nulla. Poiché non è necessario fare affidamento sui cookie, non è necessario proteggersi dalle richieste cross site (ad es., non sarebbe possibile<iframe> il tuo sito, generare una richiesta POST e riutilizzare il cookie di autenticazione esistente perché non ce ne sarà nessuno) poiché il JWT deve essere esplicitamente incluso nell’intestazione della richiesta e non viene impostato automaticamente come un cookie.
  • Buone prestazioni: è probabile che un round-trip di rete (ad esempio trovare una sessione nel database, deserializzarla, quindi estrarre le informazioni che ti interessano) richieda più tempo del calcolo di un HMACSHA256 per convalidare un token e analizzarne il contenuto.,
  • Basato su standard: Leggi le specifiche: RFC 7519 supportato da più librerie di backend (. NET, Ruby, Java, Python, PHP, Javascript) e aziende che supportano la loro infrastruttura (ad esempio, Firebase, Google, Microsoft, Zendesk).

Questo è tutto! Vai avanti e liberati dai tuoi oppressori di biscotti! E poi lasciaci un commento per farci sapere quanto è bello che la libertà si sente e condividere la liberazione con i tuoi amici inviando questo articolo a modo loro.

Scritto da: Rob McLarty

Questo articolo è stato originariamente pubblicato su http://robmclarty.com/blog

Leave A Comment