L'autenticazione è il buttafuori all'ingresso della tua applicazione. Ogni volta che qualcuno si registra o effettua l'accesso, il tuo sistema deve decidere se quella persona è chi afferma di essere. Se sbagli, non starai solo effettuando il debug di un login fallito. Stai rischiando che i dati reali degli utenti escano direttamente dalla porta. Farlo correttamente richiede due strumenti affidabili: Bcrypt per proteggere le password a riposo e i JSON Web Tokens per verificare l'identità mentre l'utente naviga nella tua app.

Perché l'archiviazione in chiaro fallisce

Se dovessi portare via un'unica regola da questo articolo, che sia questa: non memorizzare mai le password in chiaro nel tuo database. Non importa se il tuo database è protetto da un firewall o se ti fidi di ogni ingegnere del team. Scrivere le password nelle tabelle nella loro forma grezza è come lasciare le chiavi di casa sotto lo zerbino. Nel momento in cui qualcuno ottiene l'accesso a quel database — attraverso un'API configurata male, un backup trapelato o un attacco di injection — ogni credenziale viene esposta istantaneamente.

Il danno si moltiplica perché le persone riutilizzano le password. Una singola violazione può compromettere non solo la tua applicazione, ma anche l'email, i conti bancari e gli account dei social media di un utente. Ecco perché applichiamo l'hashing alle password. L'hashing trasforma la password in una stringa rimescolata che non ha alcuna somiglianza evidente con l'originale. Il processo è unidirezionale e irreversibile. Non puoi versare dell'acido matematico su un hash per scioglierlo e farlo tornare alla password che lo ha generato.

Hashing delle password con Bcrypt

Bcrypt è una funzione di hashing costruita specificamente per le password. Prende la stringa in chiaro, la passa attraverso il cifrario Blowfish e restituisce un risultato simile a $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy. Quel prefisso ti indica l'algoritmo e il fattore di costo (cost factor). La lunga coda finale è una combinazione del salt e dell'hash stesso.

Il salt è un dato casuale mescolato alla password prima dell'inizio dell'hashing. Poiché il salt è unico per ogni utente, due persone che scelgono entrambe "password123" finiranno per avere hash completamente diversi nel tuo database. Questa differenza banale sconfigge le rainbow tables — dizionari di hash precomputati per le password comuni — perché gli attaccanti dovrebbero rigenerare l'intera tabella per ogni salt univoco.

Bcrypt è anche intenzionalmente lento. L'hardware moderno può indovinare miliardi di hash al secondo con algoritmi veloci come SHA-256. Bcrypt, invece, rallenta il ritmo. Esegue il processo di hashing più volte, controllato da un fattore di costo che puoi aumentare man mano che i computer diventano più veloci. Quella lentezza punisce chiunque provi a forzare un database rubato tramite attacchi brute-force. Un utente legittimo che attende duecento millisecondi in più durante il login non se ne accorgerà. Un attaccante che cerca di testare milioni di tentativi, certamente sì.

Come funzionano i JSON Web Tokens

Mentre Bcrypt gestisce la porta d'ingresso, il JWT gestisce il pass per i corridoi. Un JSON Web Token è una stringa compatta e sicura per gli URL che dimostra che un utente è già stato autenticato. Pensalo come una carta d'identità digitale che il server rilascia e il client porta con sé.

Un JWT contiene tre segmenti separati da punti: l'header, il payload e la firma (signature). L'header specifica il tipo di token e l'algoritmo di firma. Il payload contiene i claims — dichiarazioni sull'utente e sul token stesso — come l'ID utente, il nome utente e un timestamp di scadenza. La firma è il sigillo crittografico. Il server la crea codificando l'header e il payload, per poi passarli attraverso una chiave segreta. Se qualcuno manomette il payload, la firma non corrisponderà più e il server rifiuterà immediatamente il token.