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: rappresenta la codifica delle due sezioni precedenti, criptata utilizzando una chiave segreta.
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.
Ma cosa succederebbe se, invece, John Doe avesse un ruolo diverso, ad esempio USER, e modificasse manualmente il suo ruolo? Il risultato sarebbe un token valido che consentirebbe l’accesso a un’API protetta a un utente non autorizzato.
Questo problema può essere affrontato in due modi:
- Evitando di inserire attributi importanti come il ruolo nel token.
- Se non evitabile, assicurandosi che tali attributi siano validati facendo dei controlli con i dati presenti nel database dell’applicazione.
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.
Ottimo articolo, esplicativo con contenuti semplici da assimilare