Vydali jste nový build, přešli na VPN a stejná obrazovka se přestala načítat. Na Androidu 9 a novějším je častější vysvětlení nudnější: platforma odmítá obyčejné HTTP u aplikací, které cílí na API 28 nebo vyšší, a VPN změnila jen tolik kontextu, aby to odhalila. Chyba, kterou dostanete, závisí na HTTP klientovi, a proto tak zřídka říká cleartext.

Co to selhání vlastně je

Od Androidu 9 platforma ve výchozím nastavení blokuje cleartext, jakmile aplikace cílí na úroveň API 28 nebo vyšší. Požadavek na obyčejnou HTTP adresu platforma odmítne dřív, než zařízení opustí jediný paket. Jakou chybu uvidíte, závisí na HTTP knihovně: někdy obecné selhání sítě, někdy vypršení času, někdy zpráva, která cleartext výslovně pojmenuje. Nikdy ale nedojde na váš server. Android dokumentuje výchozí chování i alternativu omezenou na domény ve své příručce ke konfiguraci zabezpečení.

Prohlížeč na stejném zařízení stránku pořád načte, a to je stopa, kterou většina lidí přehlédne. Prohlížeče se neřídí síťovou bezpečnostní politikou vaší aplikace.

Proč se viní VPN

Obvykle se mění tři věci najednou. Aplikace může po připojení VPN přeložit jiné jméno hostitele, zařízení může být nové s novějším buildem, nebo se samotný build mohl posunout na cílovou úroveň API, která výchozí chování spustí. VPN je vidět a cílový SDK ne, takže lístek dostane VPN.

Porovnejte cílové úrovně starého a nového buildu, než sáhnete na síťovou konfiguraci. Aplikace cílící na 27 nebo níž je vyňatá, což vysvětluje každé hlášení „mně to na starším telefonu funguje“.

Kam příznak Expo doopravdy dopadne

Ve spravovaném projektu Expo přidání nastavení do app.json needituje androidí manifest, protože manifest vytvářejí prebuild a vývojové buildy. Nastavení v té fázi zapisuje konfigurační plugin. Podporovaná cesta je expo-build-properties, nastavený v konfiguraci aplikace s volbou cleartext pod android.

{
  "plugins": [
    ["expo-build-properties", {
      "android": { "usesCleartextTraffic": true }
    }]
  ]
}

Úryvek nastaví jen volbu pluginu; manifest vzniká později. Spusťte prebuild nebo čerstvý build vývojového klienta, a pak před novým testem zkontrolujte vygenerovaný AndroidManifest.xml na android:usesCleartextTraffic, protože pouhé načtení JS znovu ponechá starý manifest. Slaďte verzi pluginu s Expo SDK, na kterém projekt běží. Volby pluginu se mezi vydáními posouvají a úryvek zkopírovaný z jiného SDK je spolehlivým zdrojem tichých no-opů.

Bare postup a užší možnost

U bare React Native je ekvivalentem android:usesCleartextTraffic na elementu application, nebo síťová bezpečnostní konfigurace, která povoluje cleartext jen pro pojmenované domény. Forma omezená na domény je ta, kterou je lepší zvolit, protože povolí interní API a všechno ostatní nechá na HTTPS. Také dokumentuje svůj vlastní seznam výjimek, a to je část, na kterou se recenzent zeptá.

Ani jeden přístup nemění výchozí chování platformy pro nic, co jste nepojmenovali.

Nejdřív to dokažte z logu zařízení

Než začnete editovat konfiguraci, získejte přesné selhání. adb logcat na připojeném zařízení ukáže odmítnutí cleartextu platformou a pojmenuje komponentu, která ho vyvolala. Odmítnutý socket, jméno, které se nepřeloží, nebo neúspěšný TLS handshake ukazují úplně jinam, a zapnutí cleartextu by aplikaci jen zbytečně oslabilo.

Pak držte produkci poctivou. Cleartext je přijatelný pro laboratorní endpoint, který nemůže nabídnout TLS, a jen na nejkratší dobu, kterou dokážete naplánovat. Pokud API umí ukončit TLS uvnitř privátní sítě, dejte certifikát do úložiště důvěryhodných certifikátů zařízení a nechte cleartext vypnutý, protože tunel šifruje cestu ke svému výstupu a nic za ním.

Jakmile endpoint odpoví po HTTPS, oprávnění odeberte, znovu sestavte a otestujte na VPN i na běžné Wi-Fi ve stejné relaci. Překlad jmen se mezi těmito dvěma cestami může lišit a jen dvojice vám řekne, která mluví pravdu.

Související články