EN · DE · RU · FR · ES

#2762: webauthn.js

projectforge-webapp/src/utilities/webauthn.js Утилиты преобразования учётных данных WebAuthn · projectforge-webapp/src/utilities/webauthn-json.js 86 строк · 80 кода · 1 комментарий · 5 пустых
Собственный слой преобразования учётных данных WebAuthn (FIDO2/U2F) от ProjectForge. Этот модуль обеспечивает мост кодирования/декодирования между нативным API PublicKeyCredential браузера (который использует двоичные значения ArrayBuffer) и серверным JSON API (который ожидает строки в формате base64url). Три основные функции обрабатывают отдельные этапы жизненного цикла: convertPublicKeyCredentialRequestOptions декодирует предоставленные сервером challenge/идентификаторы пользователя в форму ArrayBuffer для API браузера; convertRegisterCredential упаковывает только что созданные учётные данные в JSON-форму, которую ожидает сервер для регистрации; convertAuthenticateCredential делает то же самое для аутентификационных утверждений.

Архитектура

Внутренние вспомогательные функции

decodeBase64url — Преобразует URL-безопасную строку base64 в ArrayBuffer. Использует мост atob: сначала восстанавливает стандартный base64 (заменяя -+, _/, добавляя дополнение), затем декодирует через atob и копирует charCode каждого символа в Uint8Array, основанный на новом ArrayBuffer.

bufferToBase64url — Обратная операция: перебирает представление Uint8Array, строит двоичную строку через String.fromCharCode, кодирует с помощью btoa, затем преобразует в URL-безопасную форму.

convertCredentials — Вспомогательная функция, выделенная в ходе рефакторинга, которая преобразует массив объектов дескрипторов учётных данных (с полями rawId и id) из строк base64url в ArrayBuffer для списков allowCredentials и excludeCredentials.

Регистрация и аутентификация

Регистрация (convertRegisterCredential) упаковывает: rawId, clientDataJSON, attestationObject и transports из ответа учётных данных, а также метаданные запроса (requestId, challenge, sessionToken). Аутентификация (convertAuthenticateCredential) упаковывает: authenticatorData, signature, userHandle вместо полей аттестации. Обе обёртывают результат в одну и ту же структуру конверта, которую ожидают серверные REST-эндпоинты.

Эволюция подхода

Этот файл представляет собой производственную реализацию WebAuthn, отличную от вендорной библиотеки webauthn-json.js. Команда начинала с ручного декодирования base64 с помощью битовых манипуляций (с использованием обратной таблицы поиска), затем выполнила рефакторинг в пользу более простого подхода на основе atob/btoa. Отдельные функции регистрации/аутентификации и вспомогательная функция convertCredentials были выделены из первоначально монолитного преобразования учётных данных.

История Git

КоммитЧто изменилось
9c86a74e5Выделил встроенные циклы преобразования allowCredentials/excludeCredentials в общую вспомогательную функцию convertCredentials(dest, src). Сократил дублирование: теперь оба списка учётных данных вызывают одну и ту же функцию. Также здесь было добавлено преобразование excludeCredentials из оригинального convertPublicKeyCredentialRequestOptions, завершив обработку списков учётных данных.
c6ba8d11cДва значительных дополнения: (1) Добавлено преобразование списка учётных данных внутри convertPublicKeyCredentialRequestOptions для обработки массивов allowCredentialsrawId и id каждого учётного данного декодируются из base64url; (2) Добавлена convertAuthenticateCredential как выделенная функция для аутентификационных утверждений (ранее регистрация и аутентификация обрабатывались одной функцией convertCredential). Старая функция была переименована в convertRegisterCredential для уточнения её назначения.
4c5cc21e9Выполнен рефакторинг convertCredential для прямого возврата объекта результата вместо присваивания промежуточной переменной result, а также добавлено поле challenge в выходной конверт — критическое исправление, поскольку серверу требуется оригинальный challenge для проверки учётных данных.
4a70ca329Исправлено извлечение полей ответа учётных данных с помощью деструктуризации: const { response } = credential; — предыдущий код некорректно читал clientDataJSON, attestationObject и transports из объекта credential верхнего уровня вместо credential.response, что приводило к значениям undefined. Это было критическое исправление ошибки.
ddccb2e68Крупный рефакторинг подхода к кодированию/декодированию base64url. Оригинальный ручной декодер с битовыми манипуляциями (с использованием обратной таблицы поиска и ручного сдвига битов) был заменён на более простой подход на основе atob/btoa. Также convertPublicKeyCredentialRequestOptions был преобразован с мутационного (изменение входных данных на месте) на копирующий (с использованием JSON.parse(JSON.stringify(...)) для глубокого клонирования). Добавлена первая версия convertCredential для кодирования регистрации.
05c32c27fНачальный коммит WebAuthn: создан декодер base64url и первая версия convertPublicKeyCredentialRequestOptions. Использовалось имя параметра registerData, а доступ к challenge/user.id осуществлялся через registerData.publicKey.challenge, что отражало более раннюю форму API, которая впоследствии была упрощена.