Avete presente quando su un sito web c’è una sezione privata a cui si accede inserendo username e password? Avete mai notato che, in molti casi, una volta effettuato l’accesso, non viene più richiesto di inserire username e password per gli accessi successivi?
Nelle applicazioni web stateless, questo comportamento è implementabile utilizzando un token JWT. JWT è l’acronimo di JSON Web Token e rappresenta uno standard per lo scambio di dati, definito dalla RFC7519 del 2015.
Per semplificare, grazie a un token JWT, un utente può comunicare a un’applicazione REST la propria identità senza dover inserire username e password ogni volta.
Struttura del token
Un token JWT è costituito da 3 componenti fondamentali:
- Header: contiene informazioni sul tipo di token e sull’algoritmo di firma utilizzato
- Payload: contiene tutte le informazioni scambiate tra utente e applicazione.
- Signature: è la firma delle due sezioni precedenti, calcolata utilizzando una chiave segreta. Permette al server di verificare che il token non sia stato alterato.
Token JWT: un esempio
Per avere un’idea di com’è fatto un JWT, possiamo visitare il sito jwt.io. Qui possiamo vedere un esempio di token, la cui struttura è la seguente:
- Header
{
"alg": "HS256",
"typ": "JWT"
}
- Payload
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
- Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
Il risultato è:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
ed è possibile distinguere le 3 componenti perché sono separati da un “.” .
Personalizzare il Token JWT
Il token JWT può essere personalizzato utilizzando i Claims. I Claims sono una mappa di valori che rappresentano informazioni utili per l’utilizzo dell’applicazione. Si inseriscono all’interno del Payload e contribuiscono alla dimensione finale del token.
Ecco un esempio di Payload personalizzato:
{
"sub": "johndoe@test.it",
"firstName": "John",
"lastName": "Doe",
"iat": 1728830222,
"exp": 1728866222
}
Il token risultante sarà:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2huZG9lQHRlc3QuaXQiLCJmaXJzdE5hbWUiOiJKb2huIiwibGFzdE5hbWUiOiJEb2UiLCJpYXQiOjE3Mjg4MzAyMjIsImV4cCI6MTcyODg2NjIyMn0.OYqR8KbYa0n6-Zrx1SQKXZAeX4a2iO6xZKrkC2_wLwQ
Cosa non fare mai!
Ora che abbiamo capito cos’è un token JWT e come personalizzarlo, vediamo cosa evitare. Ci sono molti errori comuni, ma ci concentreremo su uno dei più pericolosi.
Immaginiamo di avere delle API protette da JWT, utilizzabili solo da utenti con un ruolo specifico. Il Payload del JWT di un amministratore potrebbe essere:
{
"sub": "johndoe@test.it",
"firstName": "John",
"lastName": "Doe",
"role": "ADMIN",
"iat": 1728830222,
"exp": 1728866222
}
La nostra applicazione, ricevendo questo token, identificerebbe correttamente l’utente “John Doe” e gli concederebbe l’accesso alle API riservate agli amministratori.
Il token è firmato, quindi nessuno può modificarne il contenuto senza che il server se ne accorga: se John Doe avesse il ruolo USER e lo cambiasse manualmente in ADMIN, la firma non corrisponderebbe più e il token verrebbe rifiutato (a patto che il server la verifichi davvero).
L’errore è un altro: considerare il contenuto del token sempre attuale. La firma garantisce che i dati non sono stati alterati, non che siano ancora veri. Se a John Doe viene revocato il ruolo ADMIN, il token emesso in precedenza continua a dichiararlo amministratore fino alla scadenza.
Per questo conviene:
- Usare scadenze brevi, così un dato non più valido ha vita corta.
- Per le operazioni più delicate, verificare ruolo e stato dell’utente con i dati presenti nel database dell’applicazione, invece di fidarsi del solo token.
- Non inserire nel Payload informazioni riservate: è codificato, non cifrato, e chiunque può leggerlo.
Conclusione
Il token JWT è uno standard molto diffuso per le autorizzazioni nelle applicazioni web. Per ulteriori approfondimenti, consulta questo link.
E voi, avete mai utilizzato un Token JWT nelle vostre applicazioni? Fatecelo sapere lasciando un link nel form in basso.