Le passkey rendono gli account utente più sicuri, semplici e facili da usare.
Pubblicato: 12 ottobre 2022, ultimo aggiornamento: 9 aprile 2026
L'utilizzo delle passkey migliora la sicurezza, semplifica gli accessi e sostituisce le password. A differenza delle password normali, che gli utenti devono ricordare e inserire manualmente, le passkey utilizzano i meccanismi di blocco schermo del dispositivo, come la biometria o i PIN, e riducono i rischi di phishing e furto di credenziali.
Le passkey si sincronizzano tra i dispositivi utilizzando provider di passkey come Gestore delle password di Google e portachiavi iCloud.
È necessario creare una passkey, memorizzando in modo sicuro la chiave privata nel provider di passkey insieme ai metadati necessari e alla chiave pubblica memorizzata sul server per l'autenticazione. La chiave privata emette una firma dopo la verifica dell'utente sul dominio valido, rendendo le passkey resistenti al phishing. La chiave pubblica verifica la firma senza memorizzare credenziali sensibili, rendendo le passkey resistenti al furto di credenziali.
Come funziona la creazione di una passkey
Prima che un utente possa accedere con una passkey, devi creare la passkey, associarla a un account utente e archiviare la relativa chiave pubblica sul tuo server.
Potresti chiedere agli utenti di creare una passkey in una delle seguenti situazioni:
- Durante o dopo la registrazione.
- Dopo aver eseguito l'accesso.
- Dopo aver eseguito l'accesso utilizzando una passkey di un altro dispositivo (ovvero il
authenticatorAttachmentècross-platform). - In una pagina dedicata in cui gli utenti possono gestire le proprie passkey.
Per creare una passkey, utilizzi l'API WebAuthn.
I quattro componenti del flusso di registrazione della passkey sono:
- Backend: memorizza i dettagli dell'account utente, inclusa la chiave pubblica.
- Frontend: comunica con il browser e recupera i dati necessari dal backend.
- Browser: esegue il codice JavaScript e interagisce con l'API WebAuthn.
- Fornitore di passkey: crea e memorizza la passkey. In genere si tratta di un gestore delle password come Gestore delle password di Google o di un token di sicurezza.
Prima di creare una passkey, assicurati che il sistema soddisfi i seguenti prerequisiti:
L'account utente viene verificato tramite un metodo sicuro (ad esempio, verifica via email, verifica telefonica o federazione delle identità) in un periodo di tempo significativamente breve.
Il frontend e il backend possono comunicare in modo sicuro per scambiare dati delle credenziali.
Il browser supporta WebAuthn e la creazione di passkey.
Nelle sezioni seguenti ti mostreremo come controllare la maggior parte di questi elementi.
Una volta soddisfatte queste condizioni, viene eseguita la seguente procedura per creare una passkey:
- Il sistema attiva la procedura di creazione della passkey quando l'utente avvia l'azione (ad esempio, facendo clic sul pulsante "Crea una passkey" nella pagina di gestione delle passkey o dopo aver completato la registrazione).
- Il frontend richiede i dati delle credenziali necessari dal backend, inclusi i dati utente, una sfida e gli ID credenziali per evitare duplicati.
- Il frontend chiama
navigator.credentials.create()per chiedere al provider di passkey del dispositivo di generare una passkey utilizzando le informazioni del backend. Tieni presente che questa chiamata restituisce una promessa. - Il dispositivo dell'utente autentica l'utente utilizzando un metodo biometrico, un PIN o una sequenza per creare la passkey.
- Il fornitore di passkey crea una passkey e restituisce una credenziale di chiave pubblica al frontend, risolvendo la promessa.
- Il frontend invia la credenziale della chiave pubblica generata al backend.
- Il backend memorizza la chiave pubblica e altri dati importanti per l'autenticazione futura.
- Il backend invia una notifica all'utente (ad esempio tramite email) per confermare la creazione della passkey e rilevare potenziali accessi non autorizzati.
Questa procedura garantisce una registrazione delle passkey sicura e senza problemi per gli utenti.
Compatibilità
La maggior parte dei browser supporta WebAuthn, con alcune lacune minori. Visita la pagina passkeys.dev per informazioni dettagliate sulla compatibilità con browser e sistemi operativi.
Crea una nuova passkey
Per creare una nuova passkey, il frontend deve seguire questa procedura:
- Verifica la compatibilità.
- Recupera informazioni dal backend.
- Chiama l'API WebAuth per creare una passkey.
- Invia la chiave pubblica restituita al backend.
- Salva la credenziale.
Le sezioni seguenti mostrano come fare.
Verifica la compatibilità della tua macchina
Prima di visualizzare un pulsante "Crea una nuova passkey", il frontend deve verificare se:
- Il browser supporta WebAuthn con
PublicKeyCredential.
- Il browser supporta il rilevamento delle funzionalità con
PublicKeyCredential.getClientCapabilities().
Il browser supporta l'interfaccia utente condizionale di WebAuthn con
conditionalGet.Il dispositivo supporta un autenticatore della piattaforma (può creare una passkey e autenticarsi sul dispositivo) con
passkeyPlatformAuthenticator.
Il seguente snippet di codice mostra come verificare la compatibilità prima di visualizzare le opzioni relative alle passkey.
if (window.PublicKeyCredential && PublicKeyCredential.getClientCapabilities) {
const capabilities = await PublicKeyCredential.getClientCapabilities();
if (capabilities.conditionalGet === true &&
capabilities.passkeyPlatformAuthenticator === true) {
// The browser supports passkeys and the conditional UI.
}
}
In questo esempio, il pulsante Crea una nuova passkey deve essere visualizzato solo se sono soddisfatte tutte le condizioni.
Recuperare informazioni dal backend
Quando l'utente fa clic sul pulsante, recupera le informazioni richieste dal backend per chiamare navigator.credentials.create().
Il seguente snippet di codice mostra un oggetto JSON con le informazioni necessarie per
chiamare navigator.credentials.create():
// Example `PublicKeyCredentialCreationOptions` contents
{
challenge: *****,
rp: {
name: "Example",
id: "example.com",
},
user: {
id: *****,
name: "john78",
displayName: "John",
},
pubKeyCredParams: [{
alg: -7, type: "public-key"
},{
alg: -257, type: "public-key"
}],
excludeCredentials: [{
id: *****,
type: 'public-key',
transports: ['internal'],
}],
authenticatorSelection: {
authenticatorAttachment: "platform",
requireResidentKey: true,
}
}
Le coppie chiave-valore nell'oggetto contengono le seguenti informazioni:
challenge: Una sfida generata dal server in ArrayBuffer per questa registrazione.rp.id: Un ID RP (Relying Party ID), un dominio e un sito web possono specificare il proprio dominio o un suffisso registrabile. Ad esempio, se l'origine di un RP èhttps://login.example.com:1337, l'ID RP può esserelogin.example.comoexample.com. Se l'ID RP è specificato comeexample.com, l'utente può autenticarsi sulogin.example.como su qualsiasi sottodominio diexample.com. Per saperne di più, consulta Consentire il riutilizzo delle passkey nei tuoi siti con le richieste di origine correlata.rp.name: Il nome della RP (Relying Party). Questa opzione è deprecata in WebAuthn L3, ma è inclusa per motivi di compatibilità.user.id: Un ID utente univoco in ArrayBuffer, generato al momento della creazione dell'account. Deve essere permanente, a differenza di un nome utente che può essere modificato. L'ID utente identifica un account, ma non deve contenere informazioni che consentono l'identificazione personale (PII). Probabilmente hai già un ID utente nel tuo sistema, ma se necessario, creane uno specificamente per le passkey per evitare che contenga informazioni personali.user.name: un identificatore univoco per l'account che l'utente riconoscerà, ad esempio il suo indirizzo email o nome utente. Verrà visualizzato nel selettore account.user.displayName: Un nome più facile da ricordare per l'account. Non deve essere univoco e può essere il nome scelto dall'utente. Se il tuo sito non ha un valore adatto da includere qui, passa una stringa vuota. Questa opzione può essere mostrata nel selettore dell'account a seconda del browser.pubKeyCredParams: Specifica gli algoritmi della chiave pubblica supportati dalla RP (relying party). Ti consigliamo di impostarlo su[{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}]. Specifica il supporto per ECDSA con P-256 e RSA PKCS#1 e il supporto di questi algoritmi offre una copertura completa.excludeCredentials: Un elenco di ID credenziali già registrati. Impedisce la registrazione dello stesso dispositivo due volte fornendo un elenco di ID credenziali già registrati. Il membrotransports, se fornito, deve contenere il risultato della chiamatagetTransports()durante la registrazione di ogni credenziale.authenticatorSelection.authenticatorAttachment: Imposta questo valore su"platform"insieme ahint: ['client-device']se questa creazione della passkey è un upgrade da una password, ad esempio in una promozione dopo l'accesso."platform"indica che la RP vuole un autenticatore della piattaforma (un autenticatore incorporato nel dispositivo della piattaforma) che non richiede, ad esempio, di inserire un token di sicurezza USB. L'utente ha un'opzione più semplice per creare una passkey.authenticatorSelection.requireResidentKey: imposta su un valore booleanotrue. Una credenziale rilevabile (chiave residente) memorizza le informazioni dell'utente nella passkey e consente agli utenti di selezionare l'account al momento dell'autenticazione.authenticatorSelection.userVerification: Indica se la verifica dell'utente tramite il blocco schermo del dispositivo è"required","preferred"o"discouraged". Il valore predefinito è"preferred", il che significa che l'autenticatore potrebbe saltare la verifica dell'utente. Imposta questo valore su"preferred"o ometti la proprietà.
Ti consigliamo di creare l'oggetto sul server, codificare l'ArrayBuffer
con Base64URL e recuperarlo dal frontend. In questo modo, puoi decodificare il
payload utilizzando PublicKeyCredential.parseCreationOptionsFromJSON() e passarlo
direttamente a navigator.credentials.create().
Il seguente snippet di codice mostra come recuperare e decodificare le informazioni necessarie per creare la passkey.
// Fetch an encoded `PubicKeyCredentialCreationOptions` from the server.
const _options = await fetch('/webauthn/registerRequest');
// Deserialize and decode the `PublicKeyCredentialCreationOptions`.
const decoded_options = JSON.parse(_options);
const options = PublicKeyCredential.parseCreationOptionsFromJSON(decoded_options);
...
Chiama l'API WebAuthn per creare una passkey
Chiama navigator.credentials.create() per creare una nuova passkey. L'API restituisce
una promessa, in attesa dell'interazione dell'utente che mostra una finestra di dialogo modale.
// Invoke WebAuthn to create a passkey.
const credential = await navigator.credentials.create({
publicKey: options
});
Invia la credenziale di chiave pubblica restituita al backend
Dopo la verifica dell'utente tramite il blocco schermo del dispositivo, viene creata una passkey e la promessa viene risolta restituendo un oggetto PublicKeyCredential al frontend.
La promessa può essere rifiutata per diversi motivi. Puoi gestire questi errori
controllando la proprietà name dell'oggetto Error:
InvalidStateError: sul dispositivo esiste già una passkey. All'utente non verrà mostrata alcuna finestra di dialogo di errore. Il sito non deve considerare questo come un errore. L'utente voleva registrare il dispositivo locale e lo ha fatto.NotAllowedError: l'utente ha annullato l'operazione.AbortError: l'operazione è stata interrotta.- Altre eccezioni: si è verificato un problema imprevisto. Il browser mostra una finestra di dialogo di errore all'utente.
L'oggetto delle credenziali della chiave pubblica contiene le seguenti proprietà:
id: Un ID codificato in Base64URL della passkey creata. Questo ID aiuta il browser a determinare se è presente una passkey corrispondente nel dispositivo durante l'autenticazione. Questo valore deve essere memorizzato nel database sul backend.rawId: Una versione ArrayBuffer dell'ID credenziale.response.clientDataJSON: Un ArrayBuffer codificato dei dati del client.response.attestationObject: un oggetto di attestazione codificato ArrayBuffer. Contiene informazioni importanti come un ID RP, flag e una chiave pubblica.authenticatorAttachment: Restituisce"platform"quando questa credenziale viene creata su un dispositivo compatibile con le passkey.type: questo campo è sempre impostato su"public-key".
Codifica l'oggetto con il metodo
.toJSON(), serializzalo con JSON.stringify() e invialo al server.
...
// Encode and serialize the `PublicKeyCredential`.
const _result = credential.toJSON();
const result = JSON.stringify(_result);
// Encode and send the credential to the server for verification.
const response = await fetch('/webauthn/registerResponse', {
method: 'post',
credentials: 'same-origin',
body: result
});
...
Salva la credenziale
Dopo aver ricevuto la credenziale della chiave pubblica nel backend, ti consigliamo di utilizzare una libreria lato server o una soluzione anziché scrivere il tuo codice per elaborare una credenziale della chiave pubblica.
Puoi quindi archiviare le informazioni recuperate dalle credenziali nel database per un utilizzo futuro.
Il seguente elenco include le proprietà consigliate da salvare:
- ID credenziale: L'ID credenziale restituito con la credenziale della chiave pubblica.
- Nome credenziale: il nome della credenziale. Assegna un nome in base al fornitore della passkey da cui è stata creata, che può essere identificato in base all'AAGUID.
- ID utente: l'ID utente utilizzato per creare la passkey.
- Chiave pubblica: La chiave pubblica restituita con la credenziale di chiave pubblica. Questo è necessario per verificare un'asserzione della passkey.
- Data e ora di creazione: registra la data e l'ora di creazione della passkey. È utile per identificare la passkey.
- Data e ora dell'ultimo utilizzo: registra la data e l'ora dell'ultimo utilizzo della passkey per accedere. Questo è utile per determinare quale passkey l'utente ha utilizzato (o non utilizzato).
- AAGUID: Un identificatore univoco del fornitore di passkey.
- Flag di idoneità al backup: true se il dispositivo è idoneo alla sincronizzazione delle passkey. Queste informazioni aiutano gli utenti a identificare le passkey sincronizzabili e quelle associate al dispositivo (non sincronizzabili) nella pagina di gestione delle passkey.
Segui le istruzioni più dettagliate riportate in Registrazione delle passkey lato server
Segnalare se la registrazione non riesce
Se la registrazione di una passkey non riesce, l'utente potrebbe confondersi. Se nel provider di passkey è presente una passkey disponibile per l'utente, ma la chiave pubblica associata non è memorizzata sul lato server, i tentativi di accesso con la passkey non andranno mai a buon fine ed è difficile risolvere il problema. Assicurati di comunicare all'utente se è questo il caso.
Per evitare questa condizione, puoi
segnalare una passkey sconosciuta al fornitore di passkey utilizzando l'API Signal.
Chiamando PublicKeyCredential.signalUnknownCredential() con un ID RP e un ID credenziale, l'RP può comunicare al fornitore di passkey che la credenziale specificata è stata rimossa o non esiste. Spetta al fornitore della passkey
come gestire questo segnale, ma se supportato, la passkey associata
dovrebbe essere rimossa.
// Detect authentication failure due to lack of the credential
if (response.status === 404) {
// Feature detection
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({
rpId: "example.com",
credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
});
} else {
// Encourage the user to delete the passkey from the password manager nevertheless.
...
}
}
Per saperne di più sull'API Signal, leggi Mantieni le passkey coerenti con le credenziali sul tuo server con l'API Signal.
Invia una notifica all'utente
L'invio di una notifica (ad esempio un'email) quando viene registrata una passkey aiuta gli utenti a rilevare accessi non autorizzati all'account. Se un malintenzionato crea una passkey senza che l'utente ne sia a conoscenza, la passkey rimane disponibile per abusi futuri, anche dopo la modifica della password. La notifica avvisa l'utente e aiuta a evitare questo problema.
Elenco di controllo
- Verifica l'utente (preferibilmente tramite email o un metodo sicuro) prima di consentirgli di creare una passkey.
- Impedisci la creazione di passkey duplicate per lo stesso provider di passkey utilizzando
excludeCredentials. - Salva l'AAGUID per identificare il fornitore di passkey e per denominare la credenziale per l'utente.
- Segnala se un tentativo di registrazione di una passkey non va a buon fine con
PublicKeyCredential.signalUnknownCredential(). - Invia una notifica all'utente dopo aver creato e registrato una passkey per il suo account.
Risorse
- Registrazione delle passkey lato server
- Documento Apple: Authenticating a User Through a Web Service (Autenticazione di un utente tramite un servizio web)
- Documento Google: accesso senza password con le passkey
Passaggio successivo: Accedi con una passkey tramite la compilazione automatica dei moduli.