Приложението Expo не зарежда HTTP на Android 9: причината е cleartext, не VPN
Изграждане на Expo, което вика обикновен HTTP API, се проваля на Android 9 и по-нови. Тунелът е невинен: флагът cleartext принадлежи в конфигурацията на изграждането.
Пуснахте нова сборка, минахте към VPN и същият екран спря да се зарежда. На Android 9 и по-нови по-честото обяснение е по-скучно: платформата отказва обикновен HTTP за приложения, насочени към API 28 или по-високо, а VPN просто промени достатъчно контекст, за да го покаже. Грешката, която виждате, зависи от HTTP клиента, затова той толкова рядко казва cleartext.
Какво всъщност представлява отказът
От Android 9 нататък платформата блокира cleartext по подразбиране, щом приложението се насочи към ниво на API 28 или по-високо. Заявката към обикновен HTTP адрес се отхвърля от платформата, преди дори един пакет да напусне устройството. Коя грешка ще видите, зависи от HTTP библиотеката: понякога общ мрежов отказ, понякога изтичане на времето, понякога съобщение, което директно назовава cleartext. Това, което никога не прави, е да стигне до вашия сървър. Android документира поведението по подразбиране и алтернативата, ограничена по домейн, в ръководството за конфигурация на сигурността.
Браузър на същото устройство все още може да зареди страницата и това е уликата, която повечето хора пропускат. Браузърите не се подчиняват на мрежовата политика за сигурност на вашето приложение.
Защо обвиняват VPN
Обикновено три неща се променят наведнъж. Приложението може да резолвне различно име на хост след свързване с VPN, устройството може да е ново с по-нова сборка или самата сборка да е минала към целево ниво на API, което задейства поведението по подразбиране. VPN се вижда, а целевият SDK не, затова тикетът отива при VPN.
Сравнете целевите нива на старата и новата сборка, преди да пипате мрежовата конфигурация. Приложение, насочено към 27 или по-ниско, е освободено и това обяснява всеки доклад «работи на стария ми телефон».
Къде всъщност попада флагът на Expo
В управляван проект на Expo добавянето на настройка в app.json не редактира Android манифеста, защото манифестът се произвежда от prebuild и development сборки. Настройката на този етап се записва от конфигурационен плъгин. Поддържаният път е expo-build-properties, конфигуриран в конфигурацията на приложението с опцията cleartext под android.
{
"plugins": [
["expo-build-properties", {
"android": { "usesCleartextTraffic": true }
}]
]
}Фрагментът задава само опцията на плъгина; манифестът се произвежда по-късно. Пуснете prebuild или нова сборка на development клиента, после преди повторния тест прегледайте генерирания AndroidManifest.xml за android:usesCleartextTraffic, защото презареждане само на JS запазва стария манифест. Съобразете версията на плъгина с Expo SDK, на който работи проектът. Опциите на плъгина се местят между изданията и фрагмент, копиран от друг SDK, е надежден източник на тихи действия без ефект.
Bare работният процес и по-тясната опция
За bare React Native еквивалентът е android:usesCleartextTraffic на елемента application или конфигурация за мрежова сигурност, която разрешава cleartext само за посочени домейни. Формата, ограничена по домейн, е за предпочитане, защото разрешава вътрешния API и оставя всичко останало на HTTPS. Тя също документира собствения си списък с изключения и точно за тази част ще попита рецензентът.
Нито един от двата подхода не променя поведението по подразбиране на платформата за нещо, което не сте посочили.
Първо го докажете от журнала на устройството
Преди да редактирате конфигурацията, вземете точния отказ. adb logcat на свързано устройство показва отказа на платформата за cleartext и назовава компонента, който го е предизвикал. Отхвърлен сокет, име, което не се резолвва, или неуспешно TLS ръкостискане сочат съвсем другаде и включването на cleartext само би отслабило приложението напразно.
После дръжте продукцията честна. Cleartext е приемлив за лабораторна крайна точка, която не може да предложи TLS, и то само за най-краткото време, което можете да планирате. Ако API може да терминира TLS във вътрешната мрежа, сложете сертификата в хранилището за доверие на устройството и оставете cleartext изключен, защото тунелът криптира пътя до своя изход и нищо след него.
Щом крайната точка отговаря по HTTPS, махнете разрешението, изградете отново и тествайте на VPN и на обикновен Wi-Fi в същата сесия. Резолвването на имена може да се различава между тези два пътя и само двойката показва кой казва истината.