Паролі — одна з тих речей, які ми нормалізували лише тому, що жили з ними роками. Користувачі їх забувають, використовують повторно, записують там, де не слід. Команди повинні керувати скиданнями, політиками, хешами, витоками, фішингом і підтримкою.
passkey не робить автентифікацію ідеальною, але вони усувають величезну проблему: сервер більше не повинен зберігати таємницю, якою ділиться користувач.
Що відбувається насправді
passkey є обліковими даними на основі WebAuthn. Коли користувач створює його, пристрій генерує пару ключів:
- закритий ключ, який залишається на пристрої або в менеджері паролів;
- відкритий ключ, який може зберігати сервер.
При вході на сервер не запитує «скажи мені пароль». Надішліть випадковий виклик. Пристрій підписує його закритим ключем. Сервер перевіряє підпис за допомогою відкритого ключа.
Це приємна частина: якщо базу даних викрадено, всередині немає паролів, які можна зламати. І якщо користувач потрапляє на підроблений домен, passkey для цього домену недійсний. Це не просто зручність, це конкретний захист від фішингу.
Браузер діє як міст
У браузері два основних API:
navigator.credentials.create(), щоб створити passkey;navigator.credentials.get(), щоб використовувати його під час входу.
Але важлива логіка на сервері. Сервер має згенерувати виклик, тимчасово зберегти його, перевірити відповідь, перевірити джерело та Relying Party ID, а потім створити сеанс.
Клієнтська частина повинна бути майже нудною:
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()), });
Якщо ви помітили, що використовуєте шифрування WebAuthn вручну, зупиніться. Використовуйте надійну серверну бібліотеку. Помилки тут не є «милими помилками», це діри автентифікації.
Що зберегти в базі даних
Немає потреби рятувати півсвіту. Зазвичай достатньо:
- ID облікових даних;
- відкритий ключ;
- підключений користувач;
- будь-який лічильник перевірки або метадані;
- транспорти, якщо це корисно для UX;
- назва за вибором користувача;
- дата створення та останнього використання.
Мінімальна таблиця може виглядати так:
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 );
Потім я б додав журнали аудиту та сповіщення: якщо хтось створить новий passkey у моєму обліковому записі, я хочу знати про це.
UX важливіше, ніж демонстрація
Демонстрація passkey завжди прекрасна: ви клацаєте, Face ID, і ви зайшли. Фактичний продукт складніший.
Хтось змінює телефон. Хтось використовує заблокований комп’ютер компанії. Деякі люди не розуміють, чому браузер пропонує passkey. Хтось втрачає доступ до свого пристрою.
Ось чому я б не починав із «відсьогодні жодних паролів для всіх». Я б почав так:
- passkey необов’язковий для внутрішніх користувачів;
- пропозиція створити його після успішного входу;
- сторінка облікового запису для перейменування та видалення passkey;
- чіткий запасний варіант;
- поступове розгортання в основному логіні.
Текст в інтерфейсі має бути простим. «Використовувати екран блокування пристрою» краще, ніж «автентифікуватися за допомогою облікових даних резидента FIDO2».
Помилок, яких я б уникав
Не створюйте викликів клієнту. Завдання створюється на сервері та має бути підтверджено лише один раз.
Не просто довіряйте ідентифікатору облікових даних. Вам потрібно перевірити підпис, виклик, походження та Relying Party ID.
Не видаляйте запасні версії, поки не отримаєте хороший процес відновлення. Безпарольний режим не повинен перетворюватися на «якщо ви втратите телефон, ви назавжди».
Не сприймайте passkey як суто зовнішню кнопку. Приховування кнопки не є безпекою: справжня перевірка відбувається на стороні сервера.
Passkey-перший чи passkey-дружній?
Для нового продукту ви можете спочатку подумати про passkey. Для наявної програми я віддаю перевагу дружньому до passkey: додайте passkey як рекомендований метод, виміряйте успіх і проблеми, а потім спокійно зменшіть вагу пароля.
Ідеальної міграції не відчувається. Користувач виявляє, що ввійти легше, а не те, що компанія змінила свій протокол автентифікації.
Висновок
passkey цікаві тим, що вони одночасно покращують безпеку та UX, що трапляється рідко. Вони не є чарівною паличкою: відновлення, сумісність, підтримку та розгортання ще потрібно добре розробити.
Але основна зміна сильна. Перестаньте вимагати від користувачів винаходити та захищати секрети. Ви дозволяєте пристрою підписати криптографічний доказ, прив’язаний до вашого домену. Менше людської пам’яті, менше фішингу, менше скидання паролів. Я б сказав, що до них варто ставитися серйозно.