Использование React-Native-KeyChain для защиты учетных данных мобильного приложения
Безопасность - один из важнейших факторов при создании мобильных приложений. А аутентификация пользователей - это первоочередная задача обеспечения безопасности. Таким образом, вы можете найти несколько стратегий аутентификации пользователей, отвечающих различным требованиям безопасности.
Из них два наиболее распространенных метода:
- Используя поставщика удостоверений, поддерживающий поток предоставления кода OpenID Connect, мобильное приложение получает токен обновления для получения новых токенов доступа для вызова API.
- Непосредственно сохраняйте учетные данные пользователя в приложении с помощью связки ключей после аутентификации для повторной аутентификации.
В этой статье будет рассмотрен последний подход с использованием NPM библиотеки react-native-keychain
, вызываемой для защиты хранилища учетных данных на мобильных устройствах.
Зачем нам нужен Keychain?
По умолчанию React-Native не поставляется с каким-либо методом хранения безопасных данных.
Важно! Не храните конфиденциальные данные или ключи в коде приложения. Ко всему, что включено в кодовую базу, можно получить доступ в виде простого текста, проверив пакет приложения.
Но есть два отдельных существующих решения для Android и iOS:
- Служба связки ключей iOS
- Общие настройки безопасности Android
Чтобы использовать эти две службы, вы можете написать мост самостоятельно или быстрее использовать библиотеки. Есть три стандартные библиотеки которые используют разработчики react-native-keychain
, react-native-secure-storage
и react-native-sensitive-info
.
Статистический анализ загрузок трех пакетов в течение одного года показывает, что react-native-keychain
это самая загружаемая библиотека, в которой есть все, что вам нужно.
Использование react-native-keychain в мобильных приложениях
Прежде всего, мы можем начать с установки react-native-keychain
в нашем проекте React-Native.
Установка пакетов
Установка react-native-keychain
так же проста, как установка любого из пакетов npm. Вы можете использовать как npm, так и yarn для установки пакета.
npm i react-native-keychain
yarn add react-native-keychain
Если вы используете React-Native версии 0.59 или ниже, выполните следующую команду, она свяжет вашу библиотеку с React-Native.
react-native link react-native-keychain
Если вы разрабатываете iOS, запустите pod install
в каталоге ios/
, чтобы установить зависимости iOS. Наконец, пересоберите приложение.
Затем, используя API-интерфейсы библиотеки по умолчанию, теперь вы можете получить доступ к Связке ключей iOS и общим настройкам безопасности Android.
Примечание. При использовании react-native-keychain
важно отметить, что только определенные методы совместимы с iOS или Android. Однако те, которые мы используем в этой статье, одинаково можно использовать как на Android, так и на iOS.
Вы также можете использовать некоторые особенности платформы, если у вас есть какие-либо предварительные требования, связанные с аутентификацией.
Использование библиотеки на практике
В этом примере показано, как хранить, извлекать и использовать учетные данные для повторного входа в приложение.
Шаг 1 - Сохраните учетные данные
Мы можем использовать функцию setGenericPassword
для хранения учетных данных пользователя (имени пользователя и пароля) в Связке ключей. (Примечание: по умолчанию строки могут быть сохранены с использованием их функции. При хранении объектов рекомендуется использовать JSON.stringify
).
import * as Keychain from 'react-native-keychain';
const LoginScreen = props => {
const username = 'Charuka';
const password = 'iTsAsEcReT';
await Keychain.setGenericPassword(username, password);
}
Шаг 2 - Получить учетные данные
Используйте функцию getGenericPassword
, чтобы получить сохраненные учетные данные пользователя из Связки ключей. (Примечание: по умолчанию функция возвращает String. Поэтому при извлечении объектов рекомендуется использовать JSON.parse
).
import * as Keychain from 'react-native-keychain';
const LoginScreen = props => {
const checkUserStatus = async () => {
try {
const credentials = await Keychain.getGenericPassword();
}
} catch (error) {
console.log('Keychain couldn\'t be accessed!', error);
}
}
}
Шаг 3 - Использование в реальном сценарии
В следующем фрагменте кода сначала функция checkUserStatus()
будет вызываться в хуке useEffect
во время монтирования компонента и устанавливать учетные данные пользователя, получая их из хранилища ключей. Затем функция login()
будет вызвана для входа в систему пользователя с использованием полученных учетных данных.
import React, { useState } from 'react';
import * as Keychain from 'react-native-keychain';
const LoginScreen = props => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [preLogTest, setPreLogTest] = useState(false);
useEffect(() => {
checkUserStatus();
}, []);
useEffect(() => {
if (preLogTest) {
login();
}
}, [password, email])
const checkUserStatus = async () => {
try {
const credentials = await Keychain.getGenericPassword();
if (credentials) {
setPreLogTest(true);
setEmail(credentials.username);
setPassword(credentials.password);
} else {
setLoading(false);
}
} catch (error) {
console.log('Keychain couldn\'t be accessed!', error);
setLoading(false);
}
}
const login = async () => {
try {
const response = await fetch('yoururl' + 'signin', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
});
const responseJson = await response.json();
var message = responseJson.msg;
if (responseJson.success === true) {
await Keychain.setGenericPassword(email, password);
}
}
} catch (error) {
console.error(error);
}
};
}
Шаг 4 - Удаление учетных данных
Функция resetGenericPassword
может удалить все учетные данные Связки ключей в сценарии, когда пользователи выходят из приложения.
import * as Keychain from 'react-native-keychain';
const LoginScreen = props => {
const removeCredentials = async () => {
try {
const credentials = await Keychain.resetGenericPassword();
}
} catch (error) {
console.log('Keychain couldn\'t be accessed!', error);
}
}
}
Понимание рисков с связкой ключей
Однако, когда дело доходит до разработки под Android, в React-Native Keychain есть одна распространенная ошибка.
Общие настройки не защищены на 100%. Это безопасно для хранения ваших данных, но не рекомендуется для хранения пар ключ-значение.
Общие настройки хранятся в файле, и, если разработчику удастся подключить телефон и смонтировать файловую систему, любой желающий сможет прочитать эти настройки. Стандартный ответ - использование скрытия. Он обрабатывает шифрование и дешифрование того, что хранится на корневых устройствах, но все же данные не будут 100% секретными, потому что ключ присутствует локально.
Кроме того, SharedPrefsBackedKeyChain
используется для шифрования данных. Метод хранит 256-битные ключи шифрования в SharedPreferences на устройстве. Проблема в том, что ключ шифрования и зашифрованные данные хранятся в одном месте. И шифрование становится бессмысленным.
Однако на более новых устройствах все ключи шифрования хранятся на аппаратном уровне, а не внутри самого приложения, что увеличивает защиту.
Преимущества использования React-native-keychain
Одна библиотека для доступа к iOS Keychain и Android Keystore в приложениях React-Native.
react-native-keychain
самая популярная библиотека по многим причинам. Давайте посмотрим на некоторые важные плюсы.
- Для доступа к Связке ключей устройство должно быть разблокировано.
- Связку ключей нельзя восстановить на другом устройстве.
- В устройствах ключи шифрования хранятся на аппаратном уровне.
Заключение
Исходя из моего опыта, использование react-native-keychain
- лучший вариант для хранения учетных данных в мобильных приложениях React-Native. Как я вижу, основным преимуществом является использование существующей Связки ключей iOS и общих предпочтений Android под капотом.
Как я показал выше, проще использовать библиотеку и реализовать хранение учетных данных для ваших мобильных приложений React-Native.
Я надеюсь, что обсуждаемый здесь подход окажется полезным для большинства из вас.