Ang 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.
Hindi 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.
Ano ba talaga ang nangyayari
Ang passkey ay isang kredensyal batay sa WebAuthn. Kapag ginawa ito ng user, bubuo ang device ng key pair:
- isang pribadong key, na nananatili sa device o sa password manager;
- isang pampublikong key, na maaaring i-save ng server.
Kapag 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.
Iyan 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.
Ang browser ay gumaganap bilang isang tulay
Sa browser ang dalawang pangunahing API ay:
navigator.credentials.create()upang lumikha ng passkey;navigator.credentials.get()upang gamitin ito sa panahon ng pag-login.
Ngunit 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.
Ang bahagi ng kliyente ay dapat na halos mayamot:
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()), });
Kung 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.
Ano ang ise-save sa database
Hindi na kailangang iligtas ang kalahati ng mundo. Karaniwan sapat:
- ID ng kredensyal;
- pampublikong susi;
- konektadong gumagamit;
- anumang verification counter o metadata;
- transports, kung kapaki-pakinabang para sa UX;
- pangalan na pinili ng gumagamit;
- petsa ng paglikha at huling paggamit.
Ang isang minimal na talahanayan ay maaaring magmukhang ganito:
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 );
Pagkatapos ay magdaragdag ako ng mga audit log at notification: kung may gumawa ng bagong passkey sa aking account, gusto kong malaman ang tungkol dito.
Mas mahalaga ang UX kaysa sa demo
Ang demo ng isang passkey ay palaging maganda: mag-click ka, Face ID, pasok ka na. Ang aktwal na produkto ay mas kumplikado.
May 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.
Ito ang dahilan kung bakit hindi ako magsisimula sa "mula ngayon wala nang mga password para sa lahat". Magsisimula ako ng ganito:
- passkey opsyonal para sa mga panloob na user;
- mungkahi na lumikha ng isa pagkatapos ng matagumpay na pag-login;
- pahina ng account upang palitan ang pangalan at alisin ang passkey;
- malinaw na fallback;
- unti-unting paglulunsad sa pangunahing pag-login.
Ang 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."
Mga pagkakamaling iiwasan ko
Huwag bumuo ng mga hamon sa kliyente. Ang hamon ay nilikha sa server at dapat na ma-verify nang isang beses lamang.
Huwag basta basta magtitiwala sa credential ID. Kailangan mong i-verify ang lagda, hamon, pinagmulan at Relying Party ID.
Huwag 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".
Huwag ituring ang passkey bilang purong frontend na button. Ang pagtatago ng button ay hindi seguridad: ang tunay na verification ay server-side.
Passkey-una o passkey-friendly?
Para 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.
Ang 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.
Konklusyon
Ang 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.
Ngunit 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.