Le guide du développeur sur WebAuthn et l'implémentation des clés d'accès. Téléchargez l'aide-mémoire en PDF ou utilisez ce site web pour tout avoir au même endroit.
Lukas R.
Créé: 6 mars 2024
Mis à jour: 3 juillet 2026

Cette page a été traduite automatiquement. Consultez la version originale en anglais ici.
Téléchargez l'Aide-mémoire sur les clés d'accès gratuitement pour obtenir toutes les informations.
Le guide ultime des développeurs sur les clés d'accès
Obtenez une référence axée sur les développeurs pour tout ce qui concerne les clés d'accès, couvrant la prise en charge des plateformes, le comportement des navigateurs, les meilleures pratiques en matière d'expérience utilisateur et des conseils d'intégration.

parsedCredentialPublicKey de l'objet d'attestation.L'authentification par clés d'accès repose sur deux processus, également appelés cérémonies : l'enregistrement (ou la phase d'attestation) et la connexion (ou la phase d'assertion).
Chaque phase nécessite un défi aléatoire généré par le serveur, qui est signé par l'authentificateur et renvoyé au serveur WebAuthn pour vérifier l'utilisateur.
Expérimentez les parcours passkey dans le Passkeys Debugger.
La cérémonie d'enregistrement utilise deux objets centraux : PublicKeyCredentialCreationOptions et l'attestation.
La cérémonie de connexion utilise deux objets centraux : PublicKeyCredentialRequestOptions et l'assertion.
Découvrez combien de personnes utilisent réellement les passkeys.
Pour l'enregistrement et la connexion avec des clés d'accès, il existe quatre objets principaux :
Cette section explique également l'objet authenticatorSelection, qui est utilisé dans les PublicKeyCredentialCreationOptions.
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
We hit 80% mobile passkey activation across 5M+ users without replacing our IDP.
See how VicRoads scaled passkeys to 5M+ users — alongside their existing IDP.
Read the case studyPublicKeyCredentialCreationOptions est l'objet central de la phase d'attestation (Enregistrement). Il est créé et renvoyé par le serveur WebAuthn.
{ "PublicKeyCredentialCreationOptions": { "rp": { "id": "passkeys.eu", "name": "Corbado Passkeys Demo" }, "user": { "displayName": "john.doe", "id": "dXNyLZ….DU10Tc", "name": "john@doe.com" }, "challenge": "888fix4Bus...pHHr3Y", "pubKeyCredParams": [ { "alg": -7, "type": "public-key" }, { "alg": -257, "type": "public-key" } ], "excludeCredentials": [], "authenticatorSelection": { "authenticatorAttachment": "platform", "residentKey": "required", "userVerification": "required" }, "attestation": "none", "extensions": {} } }
L'objet contient ces attributs :
name ou displayName. Pour en savoir plus, consultez la section 4.1 Schéma de base de données.BufferSource encodée en base64URL générée de manière aléatoire qui doit être signée par l'authentificateur.residentKey est requise. Voir 2.5 authenticatorSelection.none (par défaut), indirect, direct et enterprise.Abonnez-vous à notre Substack passkeys pour les dernières actualités.
PublicKeyCredentialRequestOptions est l'objet central de la phase d'assertion (Connexion). Il est créé et renvoyé par le serveur WebAuthn.
{ "publicKeyCredentialRequestOptions": { "challenge": "pT7HMA-…dFPHk", "timeout": 500, "rpId": "passkeys.eu", "userVerification": "preferred", "allowCredentials": [], "extensions": [] } }
L'objet contient ces attributs :
PublicKeyCredentialDescriptors.preferred (par défaut), required ou discouraged.Pendant la cérémonie d'Attestation / Enregistrement, l'authentificateur renvoie cette Réponse d'enregistrement. Vous pouvez l'essayer vous-même dans le débogueur de clés d'accès.
{ "authenticatorAttachment": "platform", "id": "JKZbixUfKN_aZtimefYT-OjH5dw", "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw", "response": { "attestationObject": { "fmt": "none", "attStmt": {}, "authData": { "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM", "flags": { "userPresent": true, "userVerified": true, "backupEligible": true, "backupStatus": true, "attestedData": true, "extensionData": false }, "counter": 0, "aaguid": { "raw": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd", "name": "iCloud Keychain" }, "credentialID": "JKZbixUfKN_aZtimefYT-OjH5dw", "credentialPublicKey": "pQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA", "parsedCredentialPublicKey": { "keyType": "EC2 (2)", "algorithm": "ES256 (-7)", "curve": 1, "x": "9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx0", "y": "3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA" } } }, "clientDataJSON": { "type": "webauthn.create", "challenge": "k2p6f-upzP_hc6NZvmMAxiI0VSTeQIeXXVRGW62LTj0", "origin": "https://www.passkeys-debugger.io", "crossOrigin": false }, "transports": ["hybrid", "internal"], "authenticatorData": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkNdAAAAAPv8MAcVTk7MjAtuAgVX170AFCSmW4sVHyjf2mbYpnn2E_jox-XcpQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA", "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx3cPts8hZAnzP5YWffN1hnMnD1zuaE92Z-VCoP29Xt58A", "publicKeyAlgorithm": -7 }, "type": "public-key", "clientExtensionResults": {} }
L'attestation contient des composants importants tels que attestationObject, algorithm et les drapeaux de transport.
Extrait de la spécification WebAuthn du W3C
L'attestationObject est un objet encodé en CBOR, contenant des informations sur les identifiants nouvellement créés, la clé publique et d'autres données pertinentes :
Pour en savoir plus sur les extensions.
Les clés d'accès sont générées avec des algorithmes COSE, en indiquant l'algorithme utilisé dans l'attribut algorithme de parsedCredentialPublicKey dans l'objet d'attestation.
Voici un aperçu des algorithmes COSE les plus pertinents :
La propriété transports indique les mécanismes par lesquels un authentificateur peut communiquer avec un client. Voici quelques combinaisons de valeurs courantes :
Pendant la cérémonie d'Assertion / Connexion, l'authentificateur renvoie cette Réponse de connexion. Vous pouvez l'essayer vous-même dans le débogueur de clés d'accès.
{ "id": "JKZbixUfKN_aZtimefYT-OjH5dw", "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw", "type": "public-key", "authenticatorAttachment": "platform", "response": { "authenticatorData": { "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM", "flags": { "userPresent": true, "userVerified": true, "backupEligible": true, "backupStatus": true, "attestedData": false, "extensionData": false }, "counter": 0 }, "clientDataJSON": { "type": "webauthn.get", "challenge": "GCVkITWbe2l2dttsn_DgJYvH9QPHPDo0ygWgcgI6B7U", "origin": "https://www.passkeys-debugger.io", "crossOrigin": false, "other_keys_can_be_added_here": "do not compare clientDataJSON against a template. See https://goo.gl/yabPex" }, "signature": "MEQCIA-orC8N2KKWOxyY17BWP8lB-Be5to9btXRnJZf2SLhXAiBGxJe5Eu5LwOTbsyzAYmIXHOhlC3pN7s7Q1fRLvEW57g", "userHandle": "_FKz1uwqmR_3yGq6hJntzoIFwFC_d1u_53YRELh0KlE" } }
L'assertion contient des composants importants tels que les drapeaux, la signature et le userHandle.
Voici un aperçu des drapeaux (flags) les plus pertinents et de leurs combinaisons :
La signature est utilisée pour vérifier que l'utilisateur qui tente de se connecter possède réellement la clé privée. La signature est créée en concaténant authenticatorData et clientDataHash (c'est-à-dire la version SHA-256 de ClientDataJSON) et en signant le résultat avec la clé privée (dans l'authentificateur). Pour vérifier avec la clé publique, nous concaténons également authenticatorData et clientDataHash. Si le résultat de la vérification est vrai, l'authentification est réussie.
Le userHandle est l'ID utilisateur (user_id) réel. Pour en savoir plus sur l'ID utilisateur, consultez la section 4.1 Schéma de base de données.
L'objet authenticatorSelection permet au serveur de dicter les paramètres pour l'authentificateur et la création d'identifiants avec les valeurs suivantes :
Clés résidentes (également appelées identifiants découvrables) : Les clés résidentes sont stockées sur l'authentificateur et récupérées lors de l'authentification. De cette façon, le client peut découvrir une liste de clés possibles, c'est pourquoi l'interface conditionnelle (Conditional UI) nécessite des clés résidentes. Clés non résidentes (également appelées identifiants non découvrables) : Dans le cas des clés non résidentes, l'ID d'identifiant est stocké sur le serveur et fourni lors de l'authentification. L'ID d'identifiant est un identifiant opaque dont la structure interne est spécifique à l'implémentation. Les authentificateurs peuvent stocker des clés privées directement, utiliser l'encapsulation de clé chiffrée ou dériver des clés à partir de secrets internes. Le mécanisme exact varie selon l'implémentation de l'authentificateur.
Avertissement : Si défini sur "Preferred", l'utilisateur ou son appareil peut ignorer la vérification de l'utilisateur dans le processus d'authentification (pour en savoir plus, lisez cet article).
L'interface conditionnelle (saisie automatique des clés d'accès) affiche les clés d'accès disponibles dans une liste déroulante de sélection pour l'utilisateur, lorsqu'un utilisateur a une clé résidente enregistrée auprès de la partie de confiance. Cela améliore la convivialité des clés d'accès, mais nécessite des efforts de développement supplémentaires et n'est pas disponible pour toutes les combinaisons de systèmes d'exploitation et de navigateurs.
Comme une connexion classique, l'interface conditionnelle utilise également les objets PublicKeyCredentialRequestOptions et l'assertion.
L'interface conditionnelle n'est pas (encore) disponible sur toutes les combinaisons de systèmes d'exploitation et de navigateurs. Voici un aperçu de la couverture actuelle des navigateurs (mars 2024) :
Pour un aperçu à jour, consultez ce site web.
Un code complet et minimaliste pour une méthode d'interface conditionnelle ressemble à ceci :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Interface conditionnelle</title> </head> <body> <input type="text" id="username" autocomplete="username webauthn" /> <script> async function passkeyLogin() { try { // récupère les options de requête (y compris le défi) à partir du serveur WebAuthn let options = await WebAuthnClient.getPublicKeyRequestOptions(); const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", }); const userData = await WebAuthnClient.sendSignedChallenge(credential); window.location.href = "/logged-in"; } catch (error) { console.log(error); } } passkeyLogin(); </script> </body> </html>
L'interface conditionnelle ne fonctionne qu'avec les clés résidentes / identifiants découvrables.
Il est recommandé de fournir un point de terminaison de serveur différent pour lancer la connexion de l'interface conditionnelle.
Le client doit répondre à plusieurs exigences :
Pour éviter les erreurs, le serveur doit d'abord tester la disponibilité du client avec cette fonction :
Dans le trafic réel, les problèmes de détection et de cycle de vie se manifestent souvent sous la forme de NotAllowedError ou AbortError. Utilisez ce guide des erreurs WebAuthn pour la classification attendue par rapport à inattendue, y compris les erreurs de clés d'accès natives du gestionnaire d'identifiants.
// source: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples // La disponibilité de `window.PublicKeyCredential` signifie que WebAuthn est utilisable. if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) { // Vérifie si la médiation conditionnelle est disponible. const isCMA = await PublicKeyCredential.isConditionalMediationAvailable(); if (isCMA) { // Appelle le point de terminaison de démarrage de l'authentification WebAuthn let options = await WebAuthnClient.getPublicKeyRequestOptions(); const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", }); /* ... */ } }
Le champ de saisie doit recevoir un jeton de saisie automatique HTML (autofill token), qui signale au client d'ajouter les clés d'accès à la requête en cours. Outre les clés d'accès, les jetons de saisie automatique peuvent être associés à des jetons existants, par exemple des noms d'utilisateur et des mots de passe :
<label for="name">Nom d'utilisateur :</label> <input type="text" name="name" autocomplete="username webauthn" /> <label for="password">Mot de passe :</label> <input type="password" name="password" autocomplete="current-password webauthn" />
Il n'y a pas de schéma de base de données obligatoire ou standardisé pour les serveurs WebAuthn. Cependant, cet exemple de schéma de base de données peut être utilisé pour stocker les informations requises et fournir toutes les fonctionnalités d'un serveur WebAuthn :
Les attributs en gras sont obligatoires pour une implémentation viable minimale, tandis que les autres ne sont nécessaires que pour des fonctionnalités facultatives mais utiles.
userHandle (provenant de user_id) doit ensuite être comparé pour valider le compte utilisé pour l'authentification. N'utilisez pas l'attribut user.name pour la comparaison car il peut changer au fil du temps.userHandle dans l'objet d'assertion.User DisplayName (Nom d'affichage de l'utilisateur - user.displayName) : Nom lisible et convivial qui correspond généralement au nom complet de l'utilisateur. Il est affiché à l'utilisateur, mais n'est pas utilisé lors de l'authentification.
User Name (Nom d'utilisateur - user.name) : Nom unique et lisible qui correspond généralement à une adresse e-mail ou à un nom d'utilisateur. Il peut être affiché à l'utilisateur, mais il n'est pas utilisé lors de l'authentification.
L'identifiant de la partie de confiance (rpID) est un domaine stocké dans la clé d'accès, garantissant que la clé d'accès ne fonctionne que pour le bon domaine (URL du navigateur, consultez cet article pour les applications natives). Pendant l'authentification, le rpID est vérifié par rapport à l'URL du navigateur et n'est autorisé que dans ces deux cas :
Voici des exemples de combinaisons autorisées et non autorisées :
Voici une liste d'outils et de sites web utiles pour implémenter les clés d'accès.
chrome://device-log).Pour des stratégies d'optimisation de votre expérience utilisateur des clés d'accès au-delà de l'implémentation technique, consultez nos guides sur les meilleures pratiques de création de clés d'accès et les meilleures pratiques de connexion par clé d'accès.
Si vous souhaitez implémenter les clés d'accès avec seulement quelques lignes de code dans n'importe quelle application, vous pouvez également utiliser Corbado Complete (pour les nouvelles applications) ou Corbado Connect (pour les applications existantes).
Corbado est la Authentication Intelligence Platform pour les équipes CIAM qui gèrent l'authentification client à grande échelle. Nous vous montrons ce que les logs IDP et les outils d'analytics génériques ne voient pas : quels appareils, versions d'OS, navigateurs et gestionnaires de credentials prennent en charge les passkeys, pourquoi les enrôlements ne deviennent pas des connexions, où le flux WebAuthn échoue et quand une mise à jour OS ou navigateur casse silencieusement la connexion — le tout sans remplacer Okta, Auth0, Ping, Cognito ni votre IDP interne. Deux produits : Corbado Observe ajoute l'observabilité pour les passkeys et toute autre méthode de connexion. Corbado Connect apporte des passkeys managés avec analytics intégrés (aux côtés de votre IDP). VicRoads gère les passkeys pour plus de 5M d'utilisateurs avec Corbado (+80 % d'activation passkey). Parler à un expert Passkey →
L'interface conditionnelle nécessite de vérifier la prise en charge du navigateur via PublicKeyCredential.isConditionalMediationAvailable() avant de lancer l'authentification. Le champ de saisie doit inclure le jeton HTML autocomplete="username webauthn" et l'utilisateur doit avoir une clé résidente (identifiant découvrable) enregistrée. Un point de terminaison de serveur distinct est recommandé pour gérer le flux de connexion de l'interface conditionnelle.
Au minimum, stockez l'ID d'identifiant (Credential ID), généré par l'authentificateur lors de l'enregistrement, et l'ID utilisateur (user_id), qui est renvoyé sous la forme de userHandle dans l'objet d'assertion. Utilisez l'ID d'identifiant pour rechercher le compte utilisateur associé et comparez le userHandle pour valider l'authentification. Évitez d'utiliser user.name pour la comparaison car il peut changer au fil du temps.
Les clés résidentes (identifiants découvrables) sont stockées sur l'authentificateur lui-même et récupérées lors de l'authentification, ce qui est nécessaire pour que l'interface conditionnelle fonctionne. Les clés non résidentes stockent l'ID d'identifiant sur le serveur et l'envoient à l'authentificateur lors de l'authentification. Le champ residentKey dans authenticatorSelection contrôle ce comportement avec les valeurs "required", "preferred" ou "discouraged".
Le champ userVerification contrôle si l'authentificateur doit vérifier l'utilisateur lors de la connexion, en acceptant les valeurs "required", "preferred" (par défaut) ou "discouraged". Lorsqu'il est défini sur "preferred", l'utilisateur ou son appareil peut ignorer complètement la vérification pendant le processus d'authentification, ce qui peut affaiblir la sécurité. Le définir sur "required" garantit que la vérification a toujours lieu avant la fin de l'authentification.
Découvrez comment Corbado s’intègre à votre déploiement de passkeys et à votre stack d’authentification existante.
Explorer la Console
Articles associés
Table des matières