spinny:~/writing $ less passkeys-webauthn-passwordless-authentication.md
12Ang mga password ay isa sa mga bagay na na-normalize namin dahil nakasama namin sila sa loob ng maraming taon. Ang mga gumagamit ay nakakalimutan ang mga ito, muling ginagamit ang mga ito, isulat ang mga ito kung saan hindi nila dapat. Dapat pamahalaan ng mga koponan ang mga pag-reset, patakaran, hash, leaks, phishing at suporta.34Hindi ginagawang perpekto ng passkey ang pagpapatunay, ngunit inaalis nila ang isang malaking problema: hindi na kailangang magtago ng lihim na ibinahagi sa user ang server.56## Ano ba talaga ang nangyayari78Ang passkey ay isang kredensyal batay sa WebAuthn. Kapag ginawa ito ng user, bubuo ang device ng key pair:910- isang pribadong key, na nananatili sa device o sa password manager;11- isang pampublikong key, na maaaring i-save ng server.1213Kapag nag-log in ang server ay hindi nagtatanong ng "sabihin sa akin ang password". Magpadala ng random na hamon. Pipirmahan ito ng device gamit ang pribadong key. Bine-verify ng server ang lagda gamit ang pampublikong susi.1415Iyan ang magandang bahagi: kung ang database ay ninakaw, walang mga password sa loob upang i-crack. At kung ang isang user ay napunta sa isang pekeng domain, ang passkey ay hindi wasto para sa domain na iyon. Ito ay hindi lamang kaginhawaan, ito ay konkretong proteksyon laban sa phishing.1617## Ang browser ay gumaganap bilang isang tulay1819Sa browser ang dalawang pangunahing API ay:2021- `navigator.credentials.create()` upang lumikha ng passkey;22- `navigator.credentials.get()` upang gamitin ito sa panahon ng pag-login.2324Ngunit ang mahalagang lohika ay nasa server. Dapat buuin ng server ang hamon, pansamantalang i-save ito, i-verify ang tugon, suriin ang pinagmulan at Relying Party ID, pagkatapos ay gawin ang session.2526Ang bahagi ng kliyente ay dapat na halos mayamot: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```4142Kung nakita mo ang iyong sarili na nagpapatupad ng WebAuthn encryption sa pamamagitan ng kamay, huminto. Gumamit ng isang mahusay na library sa panig ng server. Ang mga error dito ay hindi "cute na mga bug", sila ay mga butas sa pagpapatunay.4344## Ano ang ise-save sa database4546Hindi na kailangang iligtas ang kalahati ng mundo. Karaniwan sapat:4748- ID ng kredensyal;49- pampublikong susi;50- konektadong gumagamit;51- anumang verification counter o metadata;52- transports, kung kapaki-pakinabang para sa UX;53- pangalan na pinili ng gumagamit;54- petsa ng paglikha at huling paggamit.5556Ang isang minimal na talahanayan ay maaaring magmukhang ganito: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```6970Pagkatapos ay magdaragdag ako ng mga audit log at notification: kung may gumawa ng bagong passkey sa aking account, gusto kong malaman ang tungkol dito.7172## Mas mahalaga ang UX kaysa sa demo7374Ang demo ng isang passkey ay palaging maganda: mag-click ka, Face ID, pasok ka na. Ang aktwal na produkto ay mas kumplikado.7576May nagpalit ng phone. May gumagamit ng naka-lock na computer ng kumpanya. Hindi maintindihan ng ilang tao kung bakit nagmumungkahi ang browser ng passkey. May nawalan ng access sa kanilang device.7778Ito ang dahilan kung bakit hindi ako magsisimula sa "mula ngayon wala nang mga password para sa lahat". Magsisimula ako ng ganito:79801. passkey opsyonal para sa mga panloob na user;812. mungkahi na lumikha ng isa pagkatapos ng matagumpay na pag-login;823. pahina ng account upang palitan ang pangalan at alisin ang passkey;834. malinaw na fallback;845. unti-unting paglulunsad sa pangunahing pag-login.8586Ang teksto sa interface ay dapat na simple. "Gamitin ang lock screen ng iyong device" ay mas mahusay kaysa sa "patotohanan gamit ang isang residente FIDO2 kredensyal."8788## Mga pagkakamaling iiwasan ko8990Huwag bumuo ng mga hamon sa kliyente. Ang hamon ay nilikha sa server at dapat na ma-verify nang isang beses lamang.9192Huwag basta basta magtitiwala sa credential ID. Kailangan mong i-verify ang lagda, hamon, pinagmulan at Relying Party ID.9394Huwag tanggalin ang mga fallback bago ka magkaroon ng magandang daloy ng pagbawi. Ang passwordless ay hindi kailangang maging "kung mawala mo ang iyong telepono ay wala ka nang tuluyan".9596Huwag ituring ang passkey bilang purong frontend na button. Ang pagtatago ng button ay hindi seguridad: ang tunay na verification ay server-side.9798## Passkey-una o passkey-friendly?99100Para sa isang bagong produkto maaari mong isipin ang passkey-una. Para sa isang umiiral na app mas gusto ko ang passkey-friendly: idagdag ang passkey bilang isang inirerekomendang paraan, sukatin ang tagumpay at mga problema, pagkatapos ay mahinahong bawasan ang bigat ng password.101102Ang perpektong migration ay hindi nararamdaman. Natuklasan ng user na mas madali ang pag-log in, hindi na binago ng kumpanya ang protocol ng pagpapatunay nito.103104## Konklusyon105106Ang passkey ay kawili-wili dahil pinapahusay nila ang seguridad at UX sa parehong oras, na bihira. Ang mga ito ay hindi isang magic wand: ang pagbawi, pagiging tugma, suporta at paglulunsad ay nananatiling maayos na idinisenyo.107108Ngunit ang pangunahing pagbabago ay malakas. Itigil ang pagtatanong sa mga user na mag-imbento at magprotekta ng mga lihim. Hinayaan mong lumagda ang device sa isang cryptographic na patunay na nakatali sa iyong domain. Mas kaunting memorya ng tao, mas kaunting phishing, mas kaunting pag-reset ng password. Masasabi kong sulit silang seryosohin.109110## Mga Pinagmulan111112- [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 at WebAuthn: mag-login nang walang password, walang magiclines 1-116 (END) — press q to close