Protezione delle Rotte con JWT in Express.js: Guida Completa
La protezione delle rotte in un’applicazione web è essenziale per garantire che solo utenti autenticati e autorizzati possano accedere a risorse e funzionalità specifiche. JSON Web Tokens (JWT) è un metodo comune e sicuro per gestire l’autenticazione e l’autorizzazione nelle applicazioni web. In questa guida, esploreremo come proteggere le rotte della tua applicazione Express.js utilizzando JWT, dalla generazione dei token alla loro verifica.
Cos’è un JSON Web Token (JWT)?
Un JSON Web Token (JWT) è un token compatto e auto-contenuto utilizzato per la trasmissione sicura di informazioni tra due parti. Il token è composto da tre parti:
- Header: Contiene il tipo di token e l’algoritmo di hashing utilizzato.
- Payload: Contiene le dichiarazioni (claims) come l’identità dell’utente e le autorizzazioni.
- Signature: È il risultato della codifica base64 delle prime due parti, firmata con una chiave segreta.
I JWT sono particolarmente utili per l’autenticazione nelle API RESTful, poiché possono essere facilmente trasmessi come header HTTP.
Esempio di JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Perché Usare JWT?
- Sicurezza: I JWT sono firmati digitalmente, il che garantisce che i dati non siano stati alterati.
- Stateless: I JWT non richiedono la gestione della sessione sul server, il che li rende scalabili.
- Flessibilità : Possono essere usati per autenticazione, autorizzazione, e persino per scambiare informazioni tra parti diverse.
Implementare JWT in Express.js
Passo 1: Installare le Dipendenze
Per lavorare con JWT in un’applicazione Express, è necessario installare il pacchetto jsonwebtoken
.
npm install jsonwebtoken --save
Passo 2: Generare un JWT
Quando un utente si autentica con successo (ad esempio, dopo aver inserito un nome utente e una password validi), il server genera un JWT e lo restituisce all’utente. Questo token sarà utilizzato per accedere alle rotte protette.
Esempio di Generazione di un JWT
const jwt = require("jsonwebtoken");
// Chiave segreta per firmare i token
const secretKey = "supersegreto";
app.post("/login", (req, res) => {
const { username, password } = req.body;
// Qui verifichi l'utente nel database (esempio semplificato)
if (username === "utente" && password === "password") {
// Dati da includere nel payload del token
const payload = {
username: username,
role: "user",
};
// Genera il token
const token = jwt.sign(payload, secretKey, { expiresIn: "1h" });
// Restituisce il token all'utente
res.json({ token: token });
} else {
res.status(401).send("Credenziali non valide");
}
});
Passo 3: Verificare il JWT
Per proteggere una rotta, è necessario verificare il JWT che viene inviato con la richiesta. Questo viene fatto solitamente tramite un middleware che controlla se il token è presente e valido.
Esempio di Middleware di Verifica JWT
function authenticateToken(req, res, next) {
const authHeader = req.headers["authorization"];
const token = authHeader && authHeader.split(" ")[1];
if (token == null) return res.sendStatus(401); // Se il token non è presente, restituisce 401
jwt.verify(token, secretKey, (err, user) => {
if (err) return res.sendStatus(403); // Se il token non è valido, restituisce 403
req.user = user; // Salva i dati del token nell'oggetto req
next(); // Passa alla prossima middleware/rotta
});
}
Passo 4: Proteggere le Rotte
Una volta creato il middleware di autenticazione, puoi usarlo per proteggere le rotte dell’applicazione.
Esempio di Rotta Protetta
app.get("/profile", authenticateToken, (req, res) => {
res.send(`Benvenuto ${req.user.username}, questa è la tua dashboard.`);
});
In questo esempio, la rotta /profile
è accessibile solo agli utenti che forniscono un token JWT valido.
Passo 5: Autorizzazione Basata su Ruoli
Oltre all’autenticazione, puoi implementare l’autorizzazione basata su ruoli, assicurandoti che solo utenti con determinate autorizzazioni possano accedere a specifiche rotte.
Esempio di Middleware di Autorizzazione
function authorizeRole(role) {
return (req, res, next) => {
if (req.user.role !== role) {
return res.sendStatus(403); // Se l'utente non ha il ruolo richiesto, restituisce 403
}
next();
};
}
app.get("/admin", authenticateToken, authorizeRole("admin"), (req, res) => {
res.send("Benvenuto Admin");
});
In questo esempio, solo gli utenti con il ruolo admin
possono accedere alla rotta /admin
.
Best Practices per l’Uso di JWT
- Scadenza dei Token: Imposta una scadenza breve per i token (ad esempio 1 ora) e usa i token di refresh per estendere la sessione dell’utente.
- Memorizzazione dei Token: Memorizza i JWT in modo sicuro, ad esempio nei cookie HttpOnly o nello storage locale del browser.
- HTTPS: Usa HTTPS per proteggere i JWT durante la trasmissione, prevenendo attacchi man-in-the-middle.
- Blacklist dei Token: Implementa un meccanismo di blacklist per invalidare i token rubati o quando un utente si disconnette.
Conclusione
La protezione delle rotte con JWT è una pratica sicura ed efficiente per gestire l’autenticazione e l’autorizzazione nelle applicazioni Express.js. Seguendo i passi descritti in questa guida, puoi implementare facilmente un sistema di autenticazione basato su token che protegge le tue API e garantisce che solo gli utenti autorizzati possano accedere alle risorse sensibili. Utilizza le best practices per migliorare ulteriormente la sicurezza e l’affidabilità del tuo sistema di autenticazione JWT.