spinny:~/writing $ less passkeys-webauthn-passwordless-authentication.md
12Les mots de passe font partie de ces choses que nous avons normalisées simplement parce que nous vivons avec eux depuis des années. Les utilisateurs les oublient, les réutilisent, les écrivent là où ils ne devraient pas. Les équipes doivent gérer les réinitialisations, les politiques, les hachages, les fuites, le phishing et le support.34Les passkey ne rendent pas l'authentification parfaite, mais ils suppriment un énorme problème : le serveur n'a plus besoin de garder un secret partagé avec l'utilisateur.56## Que se passe-t-il réellement78Un passkey est un identifiant basé sur WebAuthn. Lorsque l'utilisateur le crée, l'appareil génère une bi-clé :910- une clé privée, qui reste sur l'appareil ou dans le gestionnaire de mots de passe ;11- une clé publique, que le serveur peut sauvegarder.1213Lors de la connexion, le serveur ne demande pas "dites-moi le mot de passe". Envoyez un défi aléatoire. L'appareil le signe avec la clé privée. Le serveur vérifie la signature avec la clé publique.1415C'est ce qui est intéressant : si la base de données est volée, il n'y a aucun mot de passe à déchiffrer. Et si un utilisateur se retrouve sur un faux domaine, le passkey n'est pas valable pour ce domaine. Ce n'est pas seulement une question de commodité, c'est une protection concrète contre le phishing.1617## Le navigateur fait office de pont1819Dans le navigateur, les deux API principaux sont :2021- `navigator.credentials.create()` pour créer un passkey ;22- `navigator.credentials.get()` pour l'utiliser lors de la connexion.2324Mais la logique importante réside dans le serveur. Le serveur doit générer le challenge, le sauvegarder temporairement, vérifier la réponse, vérifier la source et Relying Party ID, puis créer la session.2526La partie client devrait être presque ennuyeuse :2728```typescript29const options = await fetch('/api/passkeys/login/options').then((r) => r.json());3031const credential = await navigator.credentials.get({32 publicKey: PublicKeyCredential.parseRequestOptionsFromJSON(options),33});3435await fetch('/api/passkeys/login/verify', {36 method: 'POST',37 headers: { 'Content-Type': 'application/json' },38 body: JSON.stringify(credential?.toJSON()),39});40```4142Si vous vous retrouvez à mettre en œuvre le chiffrement WebAuthn à la main, arrêtez. Utilisez une bibliothèque robuste côté serveur. Les erreurs ici ne sont pas des "bugs mignons", ce sont des trous d'authentification.4344## Que sauvegarder dans la base de données4546Il n’est pas nécessaire de sauver la moitié du monde. Généralement suffisant :4748- ID du titre de compétences ;49- clé publique ;50- utilisateur connecté ;51- tout compteur de vérification ou métadonnées ;52- les transports, si utiles pour l'UX ;53- nom choisi par l'utilisateur ;54- date de création et dernière utilisation.5556Un tableau minimal pourrait ressembler à ceci :5758```sql59create table passkey_credentials (60 id uuid primary key default gen_random_uuid(),61 user_id uuid not null references users(id),62 credential_id text not null unique,63 public_key text not null,64 name text,65 created_at timestamptz not null default now(),66 last_used_at timestamptz67);68```6970Ensuite, j'ajouterais des journaux d'audit et des notifications : si quelqu'un crée un nouveau passkey sur mon compte, je veux en être informé.7172## L'UX compte plus que la démo7374La démo d'un passkey est toujours belle : vous cliquez, Face ID, vous y êtes. Le produit lui-même est plus compliqué.7576Quelqu'un change de téléphone. Quelqu'un utilise un ordinateur d'entreprise verrouillé. Certaines personnes ne comprennent pas pourquoi le navigateur suggère un passkey. Quelqu'un perd l'accès à son appareil.7778C'est pourquoi je ne commencerais pas par "à partir d'aujourd'hui, plus de mots de passe pour tout le monde". Je commencerais comme ça :79801. passkey facultatif pour les utilisateurs internes ;812. suggestion d'en créer un après une connexion réussie ;823. page du compte pour renommer et supprimer passkey ;834. repli clair ;845. déploiement progressif dans la connexion principale.8586Le texte dans l'interface doit être simple. "Utilisez l'écran de verrouillage de votre appareil" est préférable à "authentifiez-vous avec un identifiant de résident FIDO2".8788## Erreurs que j'éviterais8990Ne génèrez pas de défis sur le client. Le challenge est créé sur le serveur et ne doit être vérifié qu'une seule fois.9192Ne vous contentez pas de l'identifiant des informations d'identification. Vous devez vérifier la signature, le défi, l'origine et le Relying Party ID.9394Ne supprimez pas les solutions de secours avant d'avoir un bon flux de récupération. Le sans mot de passe ne doit pas nécessairement devenir « si vous perdez votre téléphone, vous êtes absent pour toujours ».9596Ne traitez pas le passkey comme un bouton purement frontal. Cacher un bouton n’est pas une question de sécurité : la véritable vérification se fait côté serveur.9798## Passkey-first ou passkey-friendly ?99100Pour un nouveau produit, vous pouvez penser d'abord passkey. Pour une application existante, je préfère la compatibilité passkey : ajoutez passkey comme méthode recommandée, mesurez le succès et les problèmes, puis réduisez calmement le poids du mot de passe.101102La migration idéale ne se fait pas sentir. L'utilisateur découvre que la connexion est plus facile, mais que l'entreprise n'a pas modifié son protocole d'authentification.103104## Conclusion105106Les passkey sont intéressants car ils améliorent à la fois la sécurité et l’UX, ce qui est rare. Ce n’est pas une baguette magique : la récupération, la compatibilité, le support et le déploiement restent à bien concevoir.107108Mais le changement fondamental est fort. Arrêtez de demander aux utilisateurs d’inventer et de protéger des secrets. Vous laissez l'appareil signer une preuve cryptographique liée à votre domaine. Moins de mémoire humaine, moins de phishing, moins de réinitialisations de mots de passe. Je dirais qu'ils valent la peine d'être pris au sérieux.109110##Sources111112- [MDN: Passkeys](https://developer.mozilla.org/en-US/docs/Web/Security/Authentication/Passkeys)113- [MDN: Web Authentication API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)114- [W3C: Web Authentication](https://www.w3.org/TR/webauthn-3/)115- [passkeys.dev](https://passkeys.dev/)116
:Passkey et WebAuthn : login sans mot de passe, sans magielines 1-116 (END) — press q to close