Questo articolo esplora l’uso di JSON Web Token (JWT) per autenticare servizi RESTful. Tratteremo i principi, i vantaggi e gli svantaggi di JWT, con esempi pratici in PHP.
Prerequisiti
Si richiede familiarità con l’architettura RESTful, e basi di programmazione in PHP.
Introduzione
Il bisogno di limitare l’accesso a risorse specifiche agli utenti autenticati è comune sia per applicazioni web che API. JWT offre una soluzione sicura, stateless e scalabile, rispettando i principi RESTful.
Cos’è un JSON Web Token?
Un JWT è una stringa codificata che contiene tre sezioni principali:
- Header: Contiene il tipo di token (JWT) e l’algoritmo di firma (ad esempio, HMAC-SHA256).
- Payload: Include i claims, ovvero informazioni sull’utente come ID, ruoli e scadenza del token.
- Signature: Una firma generata utilizzando una chiave segreta per garantire integrità e autenticità.
Esempio di JWT
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNjgwODg4MDAsImV4cCI6MTY4MDg5MTYwfQ.s6EoZQc9m3VfRu77E3J9PqjD5Ikg1N8d0Ilx_EBzYYQ
Autenticazione Stateless
In ambienti RESTful come micorservizi ed api delle applicazioni SPA, il server non mantiene stato tra richieste successive. JWT permette al client di inviare tutte le informazioni relative all’utente autenticato per ogni richiesta, evitando la gestione di sessioni lato server.
Vantaggi di JWT
- Scalabilità: Riduce il carico sul server.
- Efficienza: Le informazioni sono incluse nel token stesso.
- Sicurezza: La firma garantisce che i dati non siano stati alterati.
Svantaggi di JWT
- Compromissione della chiave: Se la chiave privata sul server con cui sono firmati i token viene scoperta, l’intero sistema è vulnerabile.
- Revoca complessa: Non è possibile invalidare i token senza una blacklist.
- Lunghezza del token: Può aumentare il carico di rete.
Implementazione in PHP
Generazione di un Token
require 'vendor/autoload.php';
use Firebase\JWT\JWT;
$key = "your_secret_key";
$payload = [
"iss" => "example.com",
"aud" => "example.com",
"iat" => time(),
"exp" => time() + 3600,
"user_id" => 12345,
"roles" => ["ROLE_ADMIN"]
];
$jwt = JWT::encode($payload, $key, 'HS256');
echo $jwt;
Validazione di un Token
require 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
preg_match('/Bearer\s(\S+)/', $headers['Authorization'], $matches));
$jwt = $matches[1];
$key = file_get_contents('privateKey.pem');
try {
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);
} catch (Exception $e) {
echo 'Token non valido: ', $e->getMessage();
}

