ВНЕДРЕНИЕ БИОМЕТРИКИ ДЛЯ ANDROID И ТЕСТ ЕДИНИЦЫ

Биометрия Android в React Native

Здравствуйте, уважаемый читатель, сегодня я открою (в короткой версии) свое путешествие о том, как я применил биометрические данные AndroidX в нашем проекте React Native.

Как нативный разработчик Android я участвовал в обновлении нашего существующего проекта RN. Бизнес-требование было простым:

Включите биометрическую аутентификацию для пользователей в нашем приложении. Деловое обещание - разработчики внедряют JTBD.

После первоначального исследования я нашел эту популярную библиотеку RN, которая может поддерживать биометрию.



Хорошие новости, еще один замечательный участник попытался реализовать биометрию в том же модуле, но застрял в задаче миграции «Поддержка Android на AndroidX».

По этой причине я решил повторно использовать концепцию / редизайн классов, которые были представлены в этом PR. Кроме того, я изо всех сил старался поднять уровень качества PR на более высокий уровень.

Большое спасибо автору (https://github.com/cladjules) за отличную работу.



После легкого введения давайте перейдем к «тяжелой технической части» о том, как все это работает.

Техническая глубина наших зависимостей

Как вы понимаете, путешествие началось довольно давно. У меня уже есть статья о проблемах миграции AndroidX и Android Support Library. Так что, если вы сначала прочтете его, у вас будет более глубокое понимание того, почему так легко потеряться с миграцией.



Вначале мы все (я, владелец проекта и его команда поддержки) думаем, что поддержка библиотеки поддержки Android является обязательной частью модуля. С некоторой «Божьей помощью» Facebook, наконец, выпустил версию React Native, которая «изначально» поддерживает AndroidX в проекте и заставляет наши планы измениться в лучшую сторону.

Я быстро отказываюсь от кода совместимости и переключаю код проекта на собственные зависимости AndroidX. Это снижает сложность сценариев сборки и помогает сконцентрироваться на функциональности.

Всегда сложно узнать, как настроить Android Studio для работы с React Native.

Как собственный разработчик Android, всегда критически важно иметь лучшую из возможных IDE, которая помогает в разработке кода. Для платформы Android это, конечно же, Android Studio. Трудности начинаются, когда вы понимаете, что модули React Native не являются чем-то традиционным. React Native всегда представляет собой композицию из нескольких вещей, которые выполняются одновременно на одном компьютере, например, сборщика пакетов METRO, эмулятора Android, Android Studio, ADB.

Шаг 1: составная конфигурация

Это конфигурация высокого уровня, которая управляет выполнением нескольких подконфигураций. Он состоит из трех частей: запуск приложения Android, привязка портов ADB и выполнение сборщика METRO. Если вы хотите в дополнение к этому отладочному JS-коду, вам понадобится версия IntelliJ Ultimate и одна дополнительная подконфигурация (удаленная отладка JS).

Шаг 2. Подконфигурация приложения Android

Это традиционная конфигурация средства запуска приложений Android с одним исключением: она вызывает повторную синхронизацию исходного кода при каждом запуске с помощью специальной задачи gradle.

Или вы всегда можете сделать это вручную:

# cd react-native-keychain/KeychainExample
yarn --force

# cd react-native-keychain
./gradlew updateLibrarySourcesInExample

Задача Gradle, объявленная в корневом файле build.gradle.kts проекта:

Шаг 3. Модульные тесты Android (бонус!)

Модульные тесты гарантируют, что вывод кода является ожидаемым для конкретного ввода. В каждом хорошем Android-проекте есть модульные тесты! Без исключений. Поэтому мы должны правильно настроить их в IDE.

Вы также можете сделать это из командной строки:

# cd react-native-keychain
./gradlew test

Важный! Для этого требуется специальная конфигурация градиента корневого проекта, поэтому сначала сделайте это (скопируйте / вставьте из моего репозитория), прежде чем выполнять что-то из командной строки.

Шаг 4: привязка TCP-портов ADB

Скрипт выполняет повторную привязку портов TCP каждые 5 секунд. 8081 - это порт по умолчанию для сборщика METRO в режиме разработчика, 8097 - это порт отладки для сборщика METRO (без его привязки будет невозможно подключить отладчик JavaScript и взаимодействовать с кодом React Native).

# brew install watch
/usr/local/bin/watch -n 5 "adb reverse tcp:8081 tcp:8081 && adb reverse tcp:8097 tcp:8097 && adb reverse --list"

Важный! в диалоговом окне конфигурации установите флажок «Разрешить параллельный запуск», без него ваша IDE будет зависать во время выполнения составной конфигурации.

Вам нужно то же самое для windows? Это React Native! Только Mac - единственная настоящая среда для этого разработчика.

Шаг 5: METRO Bundler

Сборщик METRO - это инструмент командной строки (CLI), который компилирует весь код JavaScript в один большой файл JS. Сборщик METRO пытается оптимизировать ваш JS-код, удалить ненужные части, свести к минимуму, затемнить и т. Д. Инструмент работает в двух режимах: релиз и разработчик. Режим выпуска предназначен для создания этого финального файла JS, максимально оптимизированного, режим разработчика предназначен для специального захвата изменений файлов JS и внедрения этих изменений в собственный двоичный файл приложения Android / iOS. Изменения доставляются в виде «дельт» между версиями, поэтому визуальная обратная связь действительно быстрая.

# set working dir to: 'react-native-keychain/KeychainExample'
/usr/bin/env node node_modules/.bin/react-native start --reset-cache

В IDE с такой конфигурацией:

Важный! в диалоговом окне конфигурации установите флажок «Разрешить параллельный запуск», без него ваша IDE будет зависать во время выполнения составной конфигурации.

Шаг 5. Отладка METRO Bundler (бонус!)

Важный! Для того, чтобы сделать возможной отладку, вы должны открыть в веб-браузере специальный URL. IntelliJ позволяет запускать Chrome-браузер без головы, что позволяет скрыть браузер с экрана, к сожалению, это работает не для всех. Поэтому я рекомендую оставить браузер Chrome с оконным интерфейсом, из него вы всегда можете переключиться на инструменты разработчика Chrome или увидеть, что несколько отладчиков пытаются получить доступ к одному и тому же URL-адресу.

Важный! И не забывайте, что сначала вы должны включить режим отладки в приложении React Native.

ссылки: https://github.com/OleksandrKucherenko/react-native-keychain/tree/android-biometric-manager/android

Изменения базовой архитектуры / дизайна после рефакторинга

Наконец, мы закончили настройку IDE и можем перейти к самому коду.

Я пропущу описание типичной библиотеки пакетов / мостов React Native, эта библиотека не является исключением со стороны разработки кода. Я просто следую стандарту и улучшаю его в нескольких местах, которые не являются тривиальными для разработчиков, не работающих с Android.

Основные изменения библиотеки:

  1. Во время запросов на расшифровку разработчик должен предоставить обработчик, если он не предоставлен, автоматически выбирает обработчик Non-Interactive. Это значит, что мы попробуем расшифровать данные, а если не удастся - не получится с исключением.
  2. В случае интерактивного обработчика будет запущена логика, которая попытается разрешить исключение, и разрешение не происходит - тогда мы потерпели неудачу с еще «большим» исключением.

Когда обязанности распределены между классами должным образом, все заработает должным образом.

Саму реализацию можно найти по ссылке:



Как имитировать API криптографической библиотеки (безопасность Java)

Реализация нашего модуля основана на Java Crypto API. Одной из сложностей использования этой библиотеки является ее различная реализация на JVM и Android. Например, в Android есть биометрия, а на обычном компьютере ее нет.

Для нас хорошо то, что крипто-API позволяет внедрять собственную реализацию - собственный завод / поставщик, который можно использовать для имитации / подделки реализации.

Реализация фейкового провайдера довольно проста:

Реализация MockForProvider:

А теперь подробности:

  1. Java Crypto API использует концепцию разделения интерфейса и реализации. Развязка использует интерфейс SPI (С службы P rovider I, или иногда ее можно назвать С спецификацией ИП) подход. Интерфейс представляет собой простой класс, который внутренне выполняет вызов фабрики, получает экземпляр SPI и реализует логику на основе вызовов различных методов SPI.
  2. Интерфейс выполняет несколько проверок и всегда ожидает, что фабрика вернет экземпляры SPI.
  3. SPI довольно скрыты от разработчика, а связь между интерфейсом и SPI недостаточно прозрачна. Вот почему так сложно издеваться над криптографическим API.
  4. Часть классов имеет защищенные или пакетные методы, которые невозможно смоделировать без специальных действий. Хорошо, что его довольно легко переопределить в модульных тестах.

Особенности биометрии для разных версий Android

Все, что связано с биометрией, следует тестировать как минимум в четырех разных версиях ОС Android:

  • API 19 - биометрическое оборудование не требуется, требуется совместимость с криптографическим API (только программное решение)
  • API 21 - нет биометрического оборудования, встроенная реализация криптографического API для Android (доступно безопасное аппаратное хранилище)
  • API 23 - доступно оборудование для отпечатков пальцев
  • API 28 - доступно различное биометрическое оборудование (отпечаток пальца, идентификатор лица и т. Д.)

Чтобы сделать возможным тестирование в этих конфигурациях, я должен использовать Robolectric или Real Devices. Мы нацелены на полную автоматизацию, поэтому тестирование на устройствах для нас - неправильный подход.

API 19: без аппаратного обеспечения, только программное обеспечение для шифрования:

API 21: без оборудования, защищенное хранилище:

API 23: Отпечатки пальцев не настроены:

API 23: биометрические параметры настроены:

API 28: Реализация другой биометрии:

Финальная полная версия тестов с разными «углами»:

И в качестве окончательного результата у нас есть множество тестов, подтверждающих нашу реализацию.

Размещение всего написанного сверху в одном большом PR:



Это конец! Биометрия внедрена, протестирована и готова к использованию!

Вы что-то узнали или хотели это обсудить? Просто сделай это! Начните разговор с этой статьи. Спасибо