Le passkey rendono gli account utente più sicuri, semplici e facili da usare.
L'utilizzo delle passkey al posto delle password è un ottimo modo per consentire ai siti web di rendere i propri account utente più sicuri, più semplici, più facili da usare e senza password. Con una passkey, un utente può accedere a un sito web o a un'app semplicemente utilizzando la propria impronta, il proprio volto o il PIN del dispositivo.
Prima che un utente possa utilizzare la passkey, è necessario creare una passkey associata a un account utente e memorizzare la sua chiave pubblica sul server.
Come funziona
A un utente può essere chiesto di creare una passkey in una delle seguenti situazioni:
- Quando un utente accede utilizzando una password.
- Quando un utente accede utilizzando una passkey da un altro dispositivo (ovvero,
authenticatorAttachment
ècross-platform
). - In una pagina dedicata in cui gli utenti possono gestire le proprie passkey.
Per creare una passkey, usa l'API WebAuthn.
I quattro componenti del flusso di registrazione tramite passkey sono:
- Backend: il tuo server di backend che contiene il database degli account in cui sono archiviati la chiave pubblica e altri metadati relativi alla passkey.
- Frontend: il frontend che comunica con il browser e invia richieste di recupero al backend.
- Browser: il browser dell'utente su cui è in esecuzione JavaScript.
- Authenticator: l'autenticatore dell'utente che crea e archivia la passkey. Ad esempio, il gestore delle password sullo stesso dispositivo del browser (ad esempio, quando usi Windows Hello) o su un altro dispositivo come un telefono.
![Diagramma di registrazione delle passkey](https://web.dev/static/articles/passkey-registration/image/passkey-registration-diagram.png?authuser=5&hl=it)
Ecco la procedura per aggiungere una nuova passkey a un account utente esistente:
- Un utente accede al sito web.
- Dopo aver eseguito l'accesso, l'utente chiede di creare una passkey sul frontend, ad esempio premendo un pulsante "Crea una passkey".
- Il frontend richiede al backend le informazioni per creare una passkey, come le informazioni sull'utente, una verifica e gli ID delle credenziali da escludere.
- Il frontend chiama
navigator.credentials.create()
per creare una passkey. Questa chiamata restituisce una promessa. - Una passkey viene creata dopo che l'utente ha dato il consenso utilizzando il blocco schermo del dispositivo. La promessa viene risolta e una credenziale di chiave pubblica viene restituita al frontend.
- Il frontend invia la credenziale della chiave pubblica al backend e archivia l'ID credenziali e la chiave pubblica associata all'account utente per le autenticazioni future.
Compatibilità
WebAuthn è supportato dalla maggior parte dei browser, ma esistono piccoli spazi vuoti. Consulta la pagina Assistenza dispositivi - passkeys.dev per scoprire quale combinazione di browser e sistemi operativi supportano la creazione di una passkey.
Crea una nuova passkey
Ecco come deve operare un frontend su una richiesta per creare una nuova passkey.
Rilevamento delle caratteristiche
Prima di visualizzare un pulsante "Crea una nuova passkey", controlla se:
- Il browser supporta WebAuthn con
PublicKeyCredential
.
- Il dispositivo supporta un autenticatore della piattaforma (può creare una passkey e
eseguire l'autenticazione con la passkey) con
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
.
- Il browser supporta l'interfaccia utente
condizionale WebAuthn con
PublicKeyCredenital.isConditionalMediationAvailable()
.
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
// `isUserVerifyingPlatformAuthenticatorAvailable` means the feature detection is usable.
// `isConditionalMediationAvailable` means the feature detection is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if user verifying platform authenticator is available.
Promise.all([
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(),
PublicKeyCredential.isConditionalMediationAvailable(),
]).then(results => {
if (results.every(r => r === true)) {
// Display "Create a new passkey" button
}
});
}
Finché tutte le condizioni non saranno soddisfatte, le passkey non saranno supportate su questo browser. Il pulsante "Crea una nuova passkey" non dovrebbe essere visualizzato prima di allora.
Recupera le informazioni importanti dal backend
Quando l'utente fa clic sul pulsante, recupera le informazioni importanti da chiamare
navigator.credentials.create()
dal backend:
challenge
: una verifica generata dal server in Arraybu per questa registrazione. Questa operazione è obbligatoria, ma non viene utilizzata durante la registrazione, a meno che non venga eseguita l'attestazione, un argomento avanzato non trattato qui.user.id
: ID univoco di un utente. Questo valore deve essere un ArrayBuffer che non include informazioni che consentono l'identificazione personale, ad esempio indirizzi email o nomi utente. Un valore casuale di 16 byte generato per account andrà bene.user.name
: Questo campo deve contenere un identificatore univoco dell'account che l'utente riconoscerà, ad esempio l'indirizzo email o il nome utente. Questo verrà visualizzato nel selettore degli account. Se utilizzi un nome utente, utilizza lo stesso valore dell'autenticazione della password.user.displayName
: Questo campo è un nome obbligatorio e più intuitivo per l'account. Non deve essere univoco e potrebbe essere il nome scelto dall'utente. Se il tuo sito non ha un valore adatto da includere qui, trasmetti una stringa vuota. A seconda del browser, potrebbe essere visualizzato sul selettore degli account.excludeCredentials
: impedisce la registrazione dello stesso dispositivo fornendo un elenco di ID credenziali già registrati. Il membrotransports
, se fornito, deve contenere il risultato della chiamata agetTransports()
durante la registrazione di ogni credenziale.
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 con la visualizzazione di una finestra di dialogo modale.
const publicKeyCredentialCreationOptions = {
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,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// Encode and send the credential to the server for verification.
I parametri non spiegati sopra sono:
rp.id
: un ID RP è un dominio e un sito web può specificare il proprio dominio o un suffisso registrabile. Ad esempio, se l'origine di una parte soggetta a limitazioni èhttps://login.example.com:1337
, l'ID della parte soggetta a limitazioni può esserelogin.example.com
oexample.com
. Se l'ID della parte soggetta a limitazioni è specificato comeexample.com
, l'utente può eseguire l'autenticazione sulogin.example.com
o su qualsiasi sottodominio suexample.com
.rp.name
: Il nome della parte soggetta a limitazioni.pubKeyCredParams
: Questo campo specifica gli algoritmi a chiave pubblica supportati dalla parte soggetta a limitazioni. Ti consigliamo di impostarlo su[{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}]
. Questo specifica il supporto per ECDSA con P-256 e RSA PKCS#1 e il supporto di questi per una copertura completa.authenticatorSelection.authenticatorAttachment
: imposta questa opzione su"platform"
se la creazione di questa passkey è un upgrade di una password, ad esempio in una promozione dopo un accesso."platform"
indica che l'RP vuole un autenticatore della piattaforma (un autenticatore incorporato nel dispositivo della piattaforma) che non richiede l'inserimento, ad esempio un token di sicurezza USB. L'utente ha un'opzione più semplice per creare una passkey.authenticatorSelection.requireResidentKey
: imposta il valore booleano "true". Una credenziale rilevabile (chiave residente) archivia le informazioni utente nella passkey e consente agli utenti di selezionare l'account al momento dell'autenticazione. Scopri di più sulle credenziali rilevabili nella pagina Approfondimento sulle credenziali rilevabiliauthenticatorSelection.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. Impostalo su"preferred"
oppure ometti la proprietà.
Invia la credenziale della chiave pubblica restituita al backend
Dopo che l'utente ha dato il consenso all'utilizzo del blocco schermo del dispositivo, viene creata una passkey e la promessa viene risolta con la restituzione di 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
: una passkey esiste già sul dispositivo. All'utente non verrà mostrata alcuna finestra di dialogo di errore e il sito non dovrebbe considerarla un errore, in quanto l'utente ha voluto registrare il dispositivo locale.NotAllowedError
: l'utente ha annullato l'operazione.- Altre eccezioni: si è verificato un problema imprevisto. Il browser mostra all'utente una finestra di dialogo di errore.
L'oggetto credenziale della chiave pubblica contiene le seguenti proprietà:
id
: un ID codificato in Base64URL della passkey creata. Questo ID consente al browser di determinare se una passkey corrispondente è presente nel dispositivo al momento dell'autenticazione. Questo valore deve essere archiviato nel database sul backend.rawId
: una versione Arraybu dell'ID credenziale.response.clientDataJSON
: Dati client codificati con Arraybu.response.attestationObject
: un oggetto di attestazione codificato con Arraybu. Questo contiene informazioni importanti come un ID parte soggetta a limitazioni, flag e una chiave pubblica.authenticatorAttachment
: restituisce"platform"
quando questa credenziale viene creata su un dispositivo che supporta una passkey.type
: questo campo è sempre impostato su"public-key"
.
Se utilizzi una libreria per gestire l'oggetto credenziali della chiave pubblica nel backend, ti consigliamo di inviare l'intero oggetto al backend dopo averlo codificato in parte con base64url.
Salva la credenziale
Dopo aver ricevuto la credenziale della chiave pubblica sul backend, passala alla libreria FIDO per elaborare l'oggetto.
Puoi quindi archiviare le informazioni recuperate dalla credenziale nel database per utilizzarle in futuro. Il seguente elenco include alcune proprietà tipiche da salvare:
- ID credenziali (chiave principale)
- User-ID
- Chiave pubblica
La credenziale di chiave pubblica include anche le seguenti informazioni che puoi salvare nel database:
- Flag per l'idoneità al backup:
true
se il dispositivo è idoneo alla sincronizzazione tramite passkey. - Flag dello stato del backup:
true
se la passkey creata è effettivamente impostata per la sincronizzazione. - Trasporti:
un elenco dei trasporti supportati dal dispositivo:
"internal"
indica che il dispositivo supporta una passkey,"hybrid"
significa che supporta anche l'autenticazione su un altro dispositivo.
Segui le istruzioni più dettagliate nella pagina Registrazione della passkey lato server
Per autenticare l'utente, leggi Accedere con una passkey tramite la compilazione automatica dei moduli.