Il sistema di autenticazione basato su password è ormai riconosciuto come il principale anello debole della sicurezza informatica. Ogni anno milioni di credenziali vengono rubate tramite phishing, data breach e attacchi di forza bruta. La soluzione definitiva esiste già e si basa su standard aperti come WebAuthn, passkeys e OAuth 2.0. Questa guida ti mostra come eliminare le password classiche dai tuoi progetti web, implementando un’autenticazione moderna, sicura e user-friendly che resista anche agli attacchi più sofisticati. Che tu sia uno sviluppatore Laravel, WordPress o di applicazioni front-end, qui troverai le basi tecniche, i flussi di implementazione e le best practice per un futuro senza password.
Il Problema delle Password Classiche
Le password presentano vulnerabilità intrinseche: vengono riutilizzate, sono deboli, intercettabili, e rappresentano il vettore primario per il credential stuffing. Secondo il Verizon Data Breach Investigations Report, oltre l'80% delle violazioni coinvolge credenziali compromesse. Inoltre, la gestione delle password genera attrito per l'utente: recupero password, reset, requisiti di complessità. L'autenticazione moderna supera questi limiti sostituendo il segreto condiviso (la password) con un meccanismo a chiave pubblica.
Per una panoramica completa sulla sicurezza web, consulta la nostra guida pillar sulla cybersecurity per sviluppatori web.
WebAuthn e Passkeys: La Base della FIDO2
Cos'è WebAuthn
Web Authentication (WebAuthn) è uno standard W3C che permette l'autenticazione tramite crittografia a chiave pubblica. Invece di inviare una password, il browser genera una coppia di chiavi (pubblica e privata). La chiave privata resta nel dispositivo dell'utente e non viene mai trasmessa. La chiave pubblica viene registrata sul server. Ogni login richiede una sfida crittografica firmata dalla chiave privata, rendendo impossibile il phishing.
Passkeys: La Semplificazione per l'Utente
Le passkeys sono l'implementazione pratica di WebAuthn pensata per l'utente comune. Possono essere legate al dispositivo (es. sensore biometrico del telefono) o sincronizzate tramite cloud (iCloud Keychain, Google Password Manager, 1Password). Le passkeys offrono resistenza al phishing perché non possono essere inserite in un form falso – la sfida viene firmata solo per il dominio corretto.
Esempio di Registrazione WebAuthn in JavaScript
Il seguente snippet mostra una registrazione WebAuthn semplificata lato client:
// Richiesta opzioni di registrazione al server
const publicKeyCredentialCreationOptions = await fetch('/webauthn/register/begin', { credentials: 'include' }).then(r => r.json());
// Creazione della credenziale
const credential = await navigator.credentials.create({ publicKey: publicKeyCredentialCreationOptions });
// Invio della risposta al server
await fetch('/webauthn/register/complete', {
method: 'POST',
body: JSON.stringify(credential),
headers: { 'Content-Type': 'application/json' }
});
Il server deve validare la risposta con una libreria come web-auth/webauthn-lib per PHP o equivalenti per Node.js. La chiave pubblica viene memorizzata associata all'utente per future autenticazioni.
Approfondisci la gestione dei tag con Google Tag Manager per tracciare eventi di login senza password.
OAuth 2.0 e Federazione delle Identità
OAuth 2.0: Delega dell'Autenticazione
OAuth 2.0 non è un protocollo di autenticazione ma di autorizzazione. Tuttavia, combinato con OpenID Connect (OIDC), permette il single sign-on e l'autenticazione federata. Eliminare le password non significa rinunciare a OAuth – anzi, le passkeys possono diventare il metodo di verifica all'interno del flusso OAuth. Ad esempio, un Identity Provider (IdP) come Google o Apple può emettere token dopo che l'utente si autentica con una passkey sul proprio device.
PKCE e Grant Code senza Secret
Per applicazioni native e SPA, l'uso di PKCE (Proof Key for Code Exchange) elimina la necessità di un client_secret, rendendo il flusso più sicuro. Il codice esempio seguente mostra l'avvio di un flusso OAuth con PKCE in JavaScript:
// Generazione code verifier e challenge
const generateCodeChallenge = async (codeVerifier) => {
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
return btoa(String.fromCharCode(...new Uint8Array(digest))).replace(/==$/, '');
};
// Redirect verso l'authorization server con code_challenge
const params = new URLSearchParams({
response_type: 'code',
client_id: 'YOUR_CLIENT_ID',
redirect_uri: 'YOUR_REDIRECT_URI',
code_challenge_method: 'S256',
code_challenge: challenge
});
window.location.href = 'https://idp.example.com/authorize?' + params;
Integrazione con Laravel e Socialite
Laravel Socialite semplifica OAuth con provider esterni. Per abilitare passkeys, si consiglia di utilizzare un middleware che controlli se l'utente ha già una passkey registrata e, in caso affermativo, saltare la password in favore della sfida WebAuthn.
Eliminare le Password: Roadmap Pratica
Fase 1: Aggiungere WebAuthn come Metodo Opzionale
Inizia implementando WebAuthn accanto alla password esistente. Offri all'utente la possibilità di registrare una passkey dopo il login con password. Usa librerie server-side mature come webauthn-lib (PHP) o @simplewebauthn/server (Node.js).
Fase 2: Rendere WebAuthn il Metodo Primario
Modifica il flusso di login: se l'utente ha una passkey, mostra prima la sfida WebAuthn; se fallisce, offri il recupero via OAuth o email magic link. Non mostrare mai la form password agli utenti con passkey attiva.
Fase 3: Rimuovere la Password
Dopo un periodo di transizione, disabilita la creazione di nuove password e imponi l'uso di passkey o OAuth per tutti gli utenti. Gestisci il recovery con processi sicuri: email verificata, backup code, o ri-registrazione tramite OAuth.
Considerazioni su Sync e Dispositivi Multipli
Le passkeys sincronizzate (via cloud) risolvono il problema della perdita del dispositivo. Per utenti che non usano cloud, offri la possibilità di registrare più passkey (es. una sul telefono, una su una chiave hardware YubiKey). Segui le linee guida FIDO Alliance per implementazioni certificate.
Best Practice e Sicurezza
Phishing Resistance
Le passkeys sono intrinsecamente resistenti al phishing: la creazione della coppia di chiavi è legata al dominio (origin). Il server deve verificare che la sfida sia firmata con la chiave privata corretta e controllare l'RP ID.
Privacy dei Biometrici
I dati biometrici (impronta, volto) non vengono mai trasmessi al server. WebAuthn utilizza solo la verifica locale nel dispositivo. Il server riceve solo la firma della sfida.
Backup e Recupero
Prevedi un meccanismo di account recovery senza password: ad esempio, invio di un codice temporaneo via email (magic link) o utilizzo di OAuth con un provider di terze parti. Non introdurre password di recupero che vanificherebbero lo scopo.
Compatibilità e Test
Tutti i browser moderni supportano WebAuthn tranne alcune eccezioni su dispositivi più datati. Utilizza feature detection per mostrare alternative. Testa con console di sviluppatore (sezione Application > WebAuthn) per simulare credenziali virtuali.
Riepilogo e Prossimi Passi. L'eliminazione delle password è possibile e auspicabile. WebAuthn e passkeys offrono sicurezza contro il phishing, mentre OAuth 2.0 con PKCE garantisce flussi federati sicuri. Inizia oggi a integrare WebAuthn nella tua applicazione Laravel o WordPress. Pianifica una migrazione graduale: aggiungi passkey, rendila primaria, poi disabilita le password. I tuoi utenti ti ringrazieranno per un'esperienza più rapida e sicura. Per un approfondimento sulla conformità GDPR in contesti di autenticazione, leggi la nostra guida GDPR per sviluppatori. Se utilizzi Livewire, consulta l'articolo su Livewire 3 e Alpine.js per integrare WebAuthn senza scrivere front-end complesso.
Sponsored Protocol