Я создаю приложение с выставкой.
Использование Axios для обработки запросов.
API имеет самоподписанные сертификаты.
Запросы не выполняются на Android 7 (они работают на Android 9)
Я прочитал в Интернете, что мне нужно добавить network_security_config.xml в манифест Android. Связь.
Как я могу сделать это на выставке (вероятно, app.json) без извлечения?
Спасибо !
Я столкнулся с аналогичной проблемой (необходимо было подключиться к локальному API с самозаверяющим сертификатом), и после смехотворного количества исследований и экспериментов я, наконец, смог найти решение. Вам нужно будет создать плагин конфигурации, для чего требуется Expo SDK версии 41+. Обратите внимание, что вы потеряете возможность использовать Expo Go, но останетесь в управляемом рабочем процессе (т. е. вам не нужно будет изменять собственный код), и вы сможете использовать сборки EAS для создания пользовательский клиент для разработчиков, который по сути представляет собой версию Expo Go, адаптированную для ваш проект.
Добавьте сертификат в список пользовательских сертификатов вашего устройства:
(Этот шаг, вероятно, не нужен, если вы включаете свой (необработанный) сертификат в приведенную ниже конфигурацию сети, см. эта ссылка.) Перейдите к Settings -> Security -> Advanced -> Encryption & credentials -> Install a certificate, чтобы импортировать сертификат
Убедитесь, что сертификат действительно является проблемой:
try {
const response = await axios.post(urlPath, payload);
} catch (error) {
console.error(error.request?._response);
}
Вы узнаете, что ваше приложение не доверяет сертификату, если вы получите сетевую ошибку и error.request._response прочитаете java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Создайте плагин:
Теперь вы создадите плагин конфигурации, который в основном представляет собой функции JS, которые запускаются на этапе prebuild Expo для изменения собственной конфигурации, такой как манифест Android, перед созданием собственного проекта.
В корне вашего проекта создайте папку plugins со следующими двумя файлами:
network_security_config.xml:<?xml version = "1.0" encoding = "utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted = "true">
<trust-anchors>
<certificates src = "system" />
<certificates src = "user" />
</trust-anchors>
</base-config>
</network-security-config>
trust-local-certs.js:const {AndroidConfig, withAndroidManifest } = require('@expo/config-plugins');
const {Paths} = require('@expo/config-plugins/build/android');
const path = require('path');
const fs = require('fs');
const fsPromises = fs.promises;
const { getMainApplicationOrThrow} = AndroidConfig.Manifest
const withTrustLocalCerts = config => {
return withAndroidManifest(config, async config => {
config.modResults = await setCustomConfigAsync(config, config.modResults);
return config;
});
}
async function setCustomConfigAsync(
config,
androidManifest
) {
const src_file_pat = path.join(__dirname, "network_security_config.xml");
const res_file_path = path.join(await Paths.getResourceFolderAsync(config.modRequest.projectRoot),
"xml", "network_security_config.xml");
const res_dir = path.resolve(res_file_path, "..");
if (!fs.existsSync(res_dir)) {
await fsPromises.mkdir(res_dir);
}
try {
await fsPromises.copyFile(src_file_pat, res_file_path);
} catch (e) {
throw e;
}
const mainApplication = getMainApplicationOrThrow(androidManifest);
mainApplication.$["android:networkSecurityConfig"] = "@xml/network_security_config";
return androidManifest;
}
module.exports = withTrustLocalCerts;
Запустите expo prebuild и свяжите плагин
Чтобы использовать плагин, у вас должен быть файл с именем app.json в корне проекта. Я не уверен на 100%, откуда я взял файл, но я считаю, что он был создан автоматически при первом запуске expo prebuild. Примечание:
prebuild (которая, по-видимому, такая же, как eject) теперь полностью обратима (например, она не устанавливает большинство дополнительных зависимостей, к которым привыкла). .expo prebuild и следуйте инструкциям -> Это должно создать файл app.json.android (и ios, если она тоже была создана).app.json добавьте следующее в конец ключа expo:
"plugins": [
"./plugins/trust-local-certs.js"
]
expo prebuild --no-install и убедитесь, что android/app/src/main/AndroidManifest.xml содержит ссылку на конфигурацию вашей сети, и что android/app/src/main/res/xml/network_security_config.xml был правильно скопирован из вашего каталога plugins.Настройте и запустите сборку EAS:
Если вы еще этого не сделали, настройте свой проект для сборок EAS с помощью следующий
эти инструкции (установите интерфейс командной строки EAS, запустите eas build:configure и настройте профиль разработчика в eas.json). Затем бегите eas build --profile development --platform android. Это создаст собственный клиент для разработчиков в облаке (плагин будет запущен на этапе prebuild), который вы сможете установить на свое устройство и который заменит Expo Go. Чтобы запустить сервер метро, запустите expo start --dev-client. После этого ваш клиент разработчика сможет подключиться к серверу Metro, и если вы снова запустите запрос axios, он должен пройти :)
Обратите внимание, что изначально я пытался встроить конфигурацию сети в манифест Android, чтобы не связываться с файлами ресурсов. К сожалению, мне пока не удалось заставить его работать (см. stackoverflow.com/q/70769075/4350421)