Créez une expérience de connexion qui utilise des clés d'accès tout en gérant les utilisateurs de mot de passe existants.
Ce guide explique comment utiliser le remplissage automatique de formulaire pour permettre aux utilisateurs de se connecter avec des clés d'accès en plus des mots de passe. L'utilisation de la saisie automatique de formulaires crée une expérience de connexion unifiée, ce qui simplifie la transition des mots de passe vers la méthode d'authentification par clé d'accès, plus sécurisée et conviviale.
Découvrez comment implémenter l'UI conditionnelle de WebAuthn pour prendre en charge les utilisateurs de clés d'accès et de mots de passe avec un minimum de friction dans vos formulaires de connexion existants.
Pourquoi utiliser le remplissage automatique de formulaire pour se connecter avec une clé d'accès ?
Les clés d'accès permettent aux utilisateurs de se connecter à des sites Web à l'aide de leur empreinte digitale, de la reconnaissance faciale ou du code de leur appareil.
Si tous les utilisateurs disposaient de clés d'accès, le flux d'authentification pourrait se limiter à un bouton de connexion unique. En appuyant sur le bouton, l'utilisateur peut valider directement le compte avec le verrouillage de l'écran et se connecter.
Toutefois, la transition des mots de passe vers les clés d'accès présente des défis. Pendant cette période, les sites Web doivent prendre en charge les utilisateurs de mots de passe et de clés d'accès. Demander aux utilisateurs de se souvenir des sites qui utilisent des clés d'accès et de choisir une méthode de connexion à l'avance nuit à l'expérience utilisateur.
Les clés d'accès sont une nouvelle technologie, et il peut être difficile de les expliquer clairement. L'utilisation de l'interface de saisie automatique familière permet de résoudre à la fois le problème de transition et le besoin de familiarité des utilisateurs.
Utiliser une UI conditionnelle
Pour prendre en charge efficacement les utilisateurs de clés d'accès et de mots de passe, incluez les clés d'accès dans les suggestions de saisie automatique de votre formulaire. Cette approche utilise l' UI conditionnelle, une fonctionnalité de la norme WebAuthn.
Lorsque l'utilisateur sélectionne le champ de saisie du nom d'utilisateur, une boîte de dialogue de saisie automatique s'affiche, suggérant les clés d'accès stockées à côté des mots de passe enregistrés. L'utilisateur peut sélectionner une clé d'accès ou un mot de passe, puis se connecter en utilisant le verrouillage de l'écran de l'appareil s'il choisit une clé d'accès.
Cela permet aux utilisateurs de se connecter à votre site Web avec le formulaire de connexion existant, mais avec l'avantage de sécurité supplémentaire des clés d'accès s'ils en ont une.
Fonctionnement de l'authentification par clé d'accès
Pour vous authentifier avec une clé d'accès, vous utilisez l'API WebAuthn.
Un flux d'authentification par clé d'accès se compose de quatre éléments :
- Backend : stocke les informations du compte utilisateur, y compris la clé publique.
- Interface : communique avec le navigateur et récupère les données nécessaires auprès du backend.
- Navigateur : exécute votre code JavaScript et interagit avec l'API WebAuthn.
- Fournisseur de clés d'accès : crée et stocke la clé d'accès. Il s'agit généralement d'un gestionnaire de mots de passe tel que le Gestionnaire de mots de passe de Google ou d'une clé de sécurité.
Le processus d'authentification par clé d'accès se déroule comme suit :
- L'utilisateur accède à la page de connexion, et le frontend demande un défi d'authentification au backend.
- Le backend génère et renvoie un challenge WebAuthn associé au compte de l'utilisateur.
- Le frontend appelle
navigator.credentials.get()avec le défi pour lancer l'authentification à l'aide du navigateur. - Le navigateur, qui interagit avec le fournisseur de clés d'accès, invite l'utilisateur à sélectionner une clé d'accès (souvent à l'aide d'une boîte de dialogue de saisie automatique déclenchée en sélectionnant le champ de connexion) et à valider son identité à l'aide du verrouillage de l'écran de l'appareil ou de la biométrie.
- Une fois l'utilisateur validé, le fournisseur de clé d'accès signe le défi, et le navigateur renvoie l'identifiant de clé publique résultant (y compris la signature) au frontend.
- Le frontend envoie cet identifiant au backend.
- Le backend valide la signature des identifiants par rapport à la clé publique stockée de l'utilisateur. Si la validation réussit, le backend connecte l'utilisateur.
S'authentifier avec une clé d'accès via le remplissage automatique de formulaire
Pour lancer l'authentification par clé d'accès à l'aide de la saisie automatique de formulaire, effectuez un appel WebAuthn get conditionnel lorsque la page de connexion se charge. Cet appel à navigator.credentials.get() inclut l'option mediation: 'conditional'.
Une requête conditionnelle à l'API WebAuthn's
navigator.credentials.get() n'affiche pas immédiatement l'UI. Au lieu de cela, il attend dans un état en attente jusqu'à ce que l'utilisateur interagisse avec l'invite de saisie automatique du champ de nom d'utilisateur. Si l'utilisateur sélectionne une clé d'accès, le navigateur résout la promesse en attente avec un identifiant pour connecter l'utilisateur, en contournant l'envoi de formulaire traditionnel. Si l'utilisateur choisit un mot de passe, la promesse n'est pas résolue et le parcours de connexion standard avec mot de passe se poursuit. La page est alors responsable de la connexion de l'utilisateur.
Annoter un champ de saisie de formulaire
Pour activer la saisie automatique des clés d'accès, ajoutez l'attribut autocomplete au champ input du nom d'utilisateur de votre formulaire. Incluez username et webauthn en tant que valeurs séparées par un espace.
<input type="text" name="username" autocomplete="username webauthn" autofocus>
Si vous ajoutez autofocus à ce champ, l'invite de saisie automatique se déclenche automatiquement au chargement de la page, affichant immédiatement les mots de passe et clés d'accès disponibles.
Détection de fonctionnalités
Avant d'appeler une API WebAuthn conditionnelle, vérifiez les points suivants :
- Le navigateur est compatible avec WebAuthn avec
PublicKeyCredential.
- Le navigateur est compatible avec la détection des fonctionnalités avec
PublicKeyCredential.getClientCapabilities().
- Le navigateur est compatible avec l'interface utilisateur conditionnelle WebAuthn avec
conditionalGet.
L'extrait suivant montre comment vérifier si le navigateur prend en charge ces fonctionnalités :
if (window.PublicKeyCredential && PublicKeyCredential.getClientCapabilities) {
const capabilities = await PublicKeyCredential.getClientCapabilities();
// Check if conditional mediation is available.
if (capabilities.conditionalGet === true) {
// The browser supports conditional mediation.
}
}
Récupérer des informations à partir du backend
Votre backend doit fournir plusieurs options au frontend pour lancer l'appel navigator.credentials.get(). Ces options sont généralement récupérées sous la forme d'un objet JSON à partir d'un point de terminaison sur votre serveur.
Voici les principales propriétés de l'objet d'options :
challenge: défi généré par le serveur dans un ArrayBuffer (généralement encodé en Base64URL pour le transport JSON). C'est essentiel pour éviter les attaques par relecture. Votre serveur doit générer un nouveau code secret pour chaque tentative de connexion et l'invalider après un court laps de temps ou en cas d'échec de la tentative.allowCredentials: tableau de descripteurs d'identifiants. Transmettez un tableau vide. Le navigateur est alors invité à lister tous les identifiants pour lerpIdspécifié.userVerification: Spécifie votre préférence pour la validation de l'utilisateur, par exemple en exigeant un verrouillage de l'écran de l'appareil. La valeur par défaut et recommandée est"preferred". Les valeurs possibles sont les suivantes :"required": l'authentificateur doit effectuer la validation de l'utilisateur (par exemple, à l'aide d'un code ou de données biométriques). L'opération échoue si la validation ne peut pas être effectuée."preferred": l'authentificateur tente de valider l'utilisateur, mais l'opération peut réussir sans cette validation."discouraged": l'authentificateur doit éviter la validation de l'utilisateur si possible.
rpId: votre ID de partie de confiance, généralement le domaine de votre site Web (par exemple,example.com). Cette valeur doit correspondre exactement à la valeurrp.idutilisée lors de la création de l'identifiant de clé d'accès.
Votre serveur doit construire cet objet d'options. Les valeurs ArrayBuffer (comme challenge) doivent être encodées en Base64URL pour le transport JSON. Sur le frontend, après avoir analysé le JSON, utilisez PublicKeyCredential.parseRequestOptionsFromJSON() pour convertir l'objet (y compris le décodage des chaînes Base64URL) au format attendu par navigator.credentials.get().
L'extrait de code suivant montre comment récupérer et décoder les informations nécessaires pour s'authentifier avec une clé d'accès.
// Fetch an encoded PubicKeyCredentialRequestOptions from the server.
const _options = await fetch('/webauthn/signinRequest');
// Deserialize and decode the PublicKeyCredentialRequestOptions.
const decoded_options = JSON.parse(_options);
const options = PublicKeyCredential.parseRequestOptionsFromJSON(decoded_options);
...
Appelez l'API WebAuthn avec l'indicateur conditional pour authentifier l'utilisateur.
Une fois que vous avez préparé l'objet publicKeyCredentialRequestOptions (appelé options dans l'exemple de code ci-dessous), appelez navigator.credentials.get() pour lancer l'authentification conditionnelle par clé d'accès.
// To abort a WebAuthn call, instantiate an AbortController.
const abortController = new AbortController();
// Invoke WebAuthn to authenticate with a passkey.
const credential = await navigator.credentials.get({
publicKey: options,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
Paramètres clés de cet appel :
publicKey: il doit s'agir de l'objetpublicKeyCredentialRequestOptions(nomméoptionsdans l'exemple) que vous avez récupéré depuis votre serveur et traité à l'étape précédente.signal: la transmission d'un signalAbortController(commeabortController.signal) vous permet d'annuler la requêteget()de manière programmatique. Cela est utile lorsque vous souhaitez appeler une autre fonction WebAuthn.mediation: 'conditional': il s'agit de l'option essentielle qui rend l'appel WebAuthn conditionnel. Il indique au navigateur d'attendre l'interaction de l'utilisateur avec une invite de saisie automatique au lieu d'afficher immédiatement une boîte de dialogue modale.
Envoyez l'identifiant de clé publique renvoyé au serveur RP.
AIf the user selects a passkey and successfully verifies their identity (for
instance, using their device screen lock), the navigator.credentials.get()
promise resolves. Cela renvoie un objet PublicKeyCredential à votre interface.
La promesse peut être refusée pour plusieurs raisons. Vous devez gérer ces erreurs dans votre code en vérifiant la propriété name de l'objet Error :
NotAllowedError: l'utilisateur a annulé l'opération ou aucune clé d'accès n'a été sélectionnée.AbortError: l'opération a été abandonnée, probablement par votre code à l'aide d'unAbortController.- Autres exceptions : une erreur inattendue s'est produite. Le navigateur affiche généralement une boîte de dialogue d'erreur à l'utilisateur.
L'objet PublicKeyCredential contient plusieurs propriétés. Voici les principales propriétés liées à l'authentification :
id: ID de la clé d'accès authentifiée, encodé en base64url.rawId: Version ArrayBuffer de l'ID des identifiants.response.clientDataJSON: ArrayBuffer de données client. Ce champ contient des informations telles que la question d'authentification et l'origine que votre serveur doit vérifier.response.authenticatorData: ArrayBuffer de données de l'authentificateur. Ce champ inclut des informations telles que l'ID de la RP.response.signature: un ArrayBuffer contenant la signature. Cette valeur est l'élément central de l'identifiant. Votre serveur doit valider cette signature à l'aide de la clé publique stockée pour l'identifiant.response.userHandle: ArrayBuffer contenant l'ID utilisateur fourni lors de l'enregistrement de la clé d'accès.authenticatorAttachment: indique si le module d'authentification fait partie de l'appareil client (platform) ou s'il est externe (cross-platform). Une pièce jointecross-platformpeut se produire si l'utilisateur s'est connecté avec un téléphone. Dans ce cas, envisagez de l'inviter à créer une clé d'accès sur l'appareil actuel pour plus de commodité à l'avenir.type: ce champ est toujours défini sur"public-key".
Pour envoyer cet objet PublicKeyCredential à votre backend, appelez d'abord la méthode .toJSON(). Cette méthode crée une version sérialisable au format JSON de l'identifiant, qui gère correctement la conversion des propriétés ArrayBuffer (comme rawId, clientDataJSON, authenticatorData, signature et userHandle) en chaînes encodées au format Base64URL. Utilisez ensuite JSON.stringify() pour convertir cet objet en chaîne et l'envoyer dans le corps de votre requête au serveur.
...
// 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/signinResponse', {
method: 'post',
credentials: 'same-origin',
body: result
});
Vérifier la signature
Lorsque votre serveur backend reçoit les identifiants de clé publique, il doit vérifier leur authenticité. ce qui implique de :
- Analyse des données d'identification.
- Recherche de la clé publique stockée associée à l'
idde l'identifiant. - Vérifiez le
signaturereçu par rapport à la clé publique stockée. - Valider d'autres données, comme le défi et l'origine
Nous vous recommandons d'utiliser une bibliothèque FIDO/WebAuthn côté serveur pour gérer ces opérations cryptographiques de manière sécurisée. Vous trouverez des bibliothèques Open Source dans le dépôt GitHub awesome-webauthn.
Si la signature et toutes les autres assertions sont valides, le serveur peut connecter l'utilisateur. Pour obtenir des informations détaillées sur les étapes de validation côté serveur, consultez Authentification par clé d'accès côté serveur.
Signaler si les identifiants correspondants ne sont pas trouvés dans le backend
Si votre serveur backend ne trouve pas d'identifiant correspondant lors de la connexion, il est possible que l'utilisateur ait précédemment supprimé cette clé d'accès de votre serveur, mais pas de son fournisseur de clés d'accès. Cette incohérence peut entraîner une expérience utilisateur déroutante si le fournisseur de clés d'accès continue de suggérer une clé d'accès qui ne fonctionne plus avec votre site. Pour améliorer cela, vous devez signaler au fournisseur de clés d'accès qu'il doit supprimer la clé d'accès orpheline.
Vous pouvez utiliser la méthode PublicKeyCredential.signalUnknownCredential(), qui fait partie de l'API Webauthn Signal, pour informer le fournisseur de clés d'accès que l'identifiant spécifié a été supprimé ou n'existe pas. Appelez cette méthode statique côté client si votre serveur indique (par exemple, avec un code d'état HTTP spécifique comme 404) qu'un ID d'identifiant présenté est inconnu. Fournissez l'ID RP et l'ID d'identifiant inconnu à cette méthode. Si le fournisseur de clés d'accès est compatible avec le signal, il doit supprimer la clé d'accès.
// 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.
...
}
}
Après l'authentification
Selon la méthode de connexion de l'utilisateur, nous suggérons différents flux à suivre.
Si l'utilisateur s'est connecté sans clé d'accès
Si l'utilisateur s'est connecté à votre site Web sans clé d'accès, il est possible qu'il n'ait pas de clé d'accès enregistrée pour ce compte ou sur son appareil actuel. C'est le moment idéal pour encourager la création de clés d'accès. Voici quelques exemples d'approches :
- Mettre à niveau les mots de passe en clés d'accès : utilisez conditional create, une fonctionnalité WebAuthn qui permet au navigateur de créer automatiquement une clé d'accès pour l'utilisateur après une connexion réussie avec un mot de passe. Cela peut considérablement améliorer l'adoption des clés d'accès en simplifiant le processus de création. Découvrez comment cela fonctionne et comment l'implémenter dans Aider les utilisateurs à adopter les clés d'accès plus facilement.
- Inviter manuellement à créer une clé d'accès : encouragez les utilisateurs à créer une clé d'accès. Cela peut être efficace après qu'un utilisateur a effectué une procédure de connexion plus complexe, comme l'authentification multifacteur (MFA). Toutefois, évitez les invites excessives, qui peuvent être intrusives pour l'expérience utilisateur."
Pour savoir comment encourager les utilisateurs à créer une clé d'accès et découvrir d'autres bonnes pratiques, consultez les exemples de la section Communiquer les clés d'accès aux utilisateurs.
Si l'utilisateur s'est connecté avec une clé d'accès
Une fois qu'un utilisateur s'est authentifié avec une clé d'accès, vous avez plusieurs possibilités d'améliorer son expérience et de maintenir la cohérence de son compte.
Encourager la création d'une clé d'accès après une authentification multi-appareils
Si un utilisateur se connecte avec une clé d'accès à l'aide d'un mécanisme multi-appareil (par exemple, en scannant un code QR avec son téléphone), la clé d'accès qu'il a utilisée peut ne pas être stockée localement sur l'appareil auquel il se connecte. Cela peut arriver dans les cas suivants :
- Il dispose d'une clé d'accès, mais chez un fournisseur de clés d'accès qui ne prend pas en charge le système d'exploitation ni le navigateur utilisés pour la connexion.
- Il n'a plus accès au fournisseur de clés d'accès sur l'appareil de connexion, mais une clé d'accès est toujours disponible sur un autre appareil.
Dans ce cas, envisagez d'inviter l'utilisateur à créer une clé d'accès sur l'appareil actuel. Cela peut leur éviter de répéter le processus de connexion multi-appareil à l'avenir. Pour déterminer si l'utilisateur s'est connecté à l'aide d'une clé d'accès multi-appareil, vérifiez la propriété authenticatorAttachment de l'identifiant. Si sa valeur est "cross-platform", cela indique une authentification multi-appareils. Si c'est le cas, expliquez-lui l'intérêt de créer une clé d'accès et guidez-le tout au long du processus de création.
Synchroniser les informations sur les clés d'accès avec le fournisseur à l'aide de signaux
Pour garantir la cohérence et une meilleure expérience utilisateur, votre Relying Party (RP) peut utiliser l'API WebAuthn Signals pour communiquer des informations sur les identifiants et les utilisateurs au fournisseur de clés d'accès.
Par exemple, pour que la liste des clés d'accès d'un utilisateur fournie par le fournisseur de clés d'accès soit exacte, synchronisez les identifiants dans le backend. Vous pouvez signaler qu'une clé d'accès n'existe plus afin que les fournisseurs de clés d'accès puissent supprimer les clés d'accès inutiles.
De même, vous pouvez signaler si un utilisateur modifie son nom d'utilisateur ou son nom à afficher sur votre service, afin de maintenir à jour les informations utilisateur affichées par le fournisseur de clés d'accès (par exemple, dans les boîtes de dialogue de sélection de compte).
Pour en savoir plus sur les bonnes pratiques permettant d'assurer la cohérence des clés d'accès, consultez Assurer la cohérence des clés d'accès avec les identifiants sur votre serveur avec l'API Signal.
Ne pas demander de second facteur
Les clés d'accès offrent une protection intégrée et robuste contre les menaces courantes telles que l'hameçonnage. Par conséquent, un second facteur d'authentification n'ajoute pas de valeur de sécurité significative. Au lieu de cela, il crée une étape inutile pour les utilisateurs lors de la connexion.
Checklist
- Autoriser les utilisateurs à se connecter avec une clé d'accès via le remplissage automatique de formulaire
- Signaler lorsqu'aucun identifiant correspondant à une clé d'accès n'est trouvé dans le backend.
- Invitez les utilisateurs à créer manuellement une clé d'accès s'ils ne l'ont pas encore fait après une connexion.
- Créer automatiquement une clé d'accès (création conditionnelle) une fois que l'utilisateur s'est connecté avec un mot de passe (et un deuxième facteur).
- Invitez l'utilisateur à créer une clé d'accès locale s'il s'est connecté avec une clé d'accès multi-appareil.
- Signalez la liste des clés d'accès disponibles et les informations utilisateur mises à jour (nom d'utilisateur, nom à afficher) au fournisseur après la connexion ou en cas de modification.
Ressources
- Authentification par clé d'accès côté serveur
- Créer une clé d'accès pour se connecter sans mot de passe
- Aider les utilisateurs à gérer efficacement les clés d'accès
- Clés d'accès
- Document Apple : Authenticating a User Through a Web Service
- Document Google : Connexion sans mot de passe avec des clés d'accès