Adgangskoder er en af de ting, vi har normaliseret, bare fordi vi har levet med dem i årevis. Brugere glemmer dem, genbruger dem, skriv dem, hvor de ikke burde. Teams skal administrere nulstillinger, politikker, hashes, lækager, phishing og support.
passkey gør ikke autentificering perfekt, men de fjerner et stort problem: serveren behøver ikke længere at holde en hemmelighed delt med brugeren.
Hvad sker der virkelig
En passkey er en legitimation baseret på WebAuthn. Når brugeren opretter det, genererer enheden et nøglepar:
- en privat nøgle, som forbliver på enheden eller i adgangskodehåndteringen;
- en offentlig nøgle, som serveren kan gemme.
Når du logger ind spørger serveren ikke "fortæl mig adgangskoden". Send en tilfældig udfordring. Enheden signerer det med den private nøgle. Serveren verificerer signaturen med den offentlige nøgle.
Det er den fine del: Hvis databasen bliver stjålet, er der ingen adgangskoder inde at knække. Og hvis en bruger ender på et falsk domæne, er passkey ikke gyldigt for det pågældende domæne. Det er ikke kun bekvemmelighed, det er konkret beskyttelse mod phishing.
Browseren fungerer som en bro
I browseren er de to vigtigste API:
navigator.credentials.create()for at oprette en passkey;navigator.credentials.get()for at bruge det under login.
Men den vigtige logik er på serveren. Serveren skal generere udfordringen, gemme den midlertidigt, verificere svaret, kontrollere kilden og Relying Party ID og derefter oprette sessionen.
Klientdelen burde være næsten kedelig:
const options = await fetch('/api/passkeys/login/options').then((r) => r.json()); const credential = await navigator.credentials.get({ publicKey: PublicKeyCredential.parseRequestOptionsFromJSON(options), }); await fetch('/api/passkeys/login/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credential?.toJSON()), });
Hvis du opdager, at du implementerer WebAuthn-kryptering i hånden, så stop. Brug et robust bibliotek på serversiden. Fejlene her er ikke "søde fejl", de er autentificeringshuller.
Hvad skal gemmes i databasen
Der er ingen grund til at redde halvdelen af verden. Normalt nok:
- ID for legitimationsoplysningerne;
- offentlig nøgle;
- tilsluttet bruger;
- enhver verifikationstæller eller metadata;
- transporter, hvis det er nyttigt for UX;
- navn valgt af brugeren;
- oprettelsesdato og sidste brug.
Et minimalt bord kan se sådan ud:
create table passkey_credentials ( id uuid primary key default gen_random_uuid(), user_id uuid not null references users(id), credential_id text not null unique, public_key text not null, name text, created_at timestamptz not null default now(), last_used_at timestamptz );
Så ville jeg tilføje revisionslogfiler og meddelelser: Hvis nogen opretter en ny passkey på min konto, vil jeg gerne vide mere om det.
UX betyder mere end demo
Demoen af en passkey er altid smuk: du klikker, Face ID, du er med. Det faktiske produkt er mere kompliceret.
Nogen skifter deres telefon. Nogen bruger en låst firmacomputer. Nogle mennesker forstår ikke, hvorfor browseren foreslår en passkey. Nogen mister adgangen til deres enhed.
Det er derfor, jeg ikke ville starte med "fra i dag ikke flere adgangskoder til alle". Jeg ville starte sådan her:
- passkey valgfrit for interne brugere;
- forslag til at oprette en efter et vellykket login;
- kontoside for at omdøbe og fjerne passkey;
- klar tilbagefald;
- gradvis udrulning i hovedlogin.
Teksten i grænsefladen skal være enkel. "Brug din enheds låseskærm" er bedre end "godkend med en beboer FIDO2 legitimationsoplysninger."
Fejl jeg ville undgå
Generer ikke udfordringer på klienten. Udfordringen oprettes på serveren og skal kun bekræftes én gang.
Stol ikke kun på legitimations-id'et. Du skal bekræfte signatur, udfordring, oprindelse og Relying Party ID.
Slet ikke fallbacks, før du har et godt genopretningsflow. Passwordless behøver ikke at blive "hvis du mister din telefon, er du ude for altid".
Behandl ikke passkey som en ren frontend-knap. At skjule en knap er ikke sikkerhed: den rigtige verifikation er server-side.
Passkey-først eller passkey-venlig?
For et nyt produkt kan du tænke passkey-først. For en eksisterende app foretrækker jeg passkey-venlig: tilføj passkey som en anbefalet metode, mål succes og problemer, og reducer derefter roligt adgangskodevægten.
Den ideelle migration mærkes ikke. Brugeren opdager, at det er nemmere at logge ind, ikke at virksomheden har ændret sin autentificeringsprotokol.
Konklusion
passkey er interessante, fordi de forbedrer sikkerhed og UX på samme tid, hvilket er sjældent. De er ikke en tryllestav: recovery, kompatibilitet, support og udrulning mangler at blive designet godt.
Men den grundlæggende forandring er stærk. Stop med at bede brugere om at opfinde og beskytte hemmeligheder. Du lader enheden underskrive et kryptografisk bevis knyttet til dit domæne. Mindre menneskelig hukommelse, mindre phishing, færre nulstillinger af adgangskode. Jeg vil sige, at de er værd at tage seriøst.