Expo-appen misslyckas med HTTP på Android 9: det är cleartext, inte VPN
En Expo-build som anropar ett vanligt HTTP-API misslyckas på Android 9 och senare. Tunneln är oskyldig: cleartext-flaggan hör hemma i byggkonfigurationen.
Du släppte en ny build, bytte till VPN och samma skärm slutade laddas. På Android 9 och senare är den vanligare förklaringen tråkigare: plattformen nekar vanlig HTTP för appar som siktar på API 28 eller högre, och VPN bytte bara tillräckligt mycket kontext för att avslöja det. Felet du får beror på HTTP-klienten, och därför säger den så sällan cleartext.
Vad felet egentligen är
Från Android 9 blockerar plattformen cleartext som standard så snart en app siktar på API-nivå 28 eller högre. Begäran till en vanlig HTTP-adress avvisas av plattformen innan ett enda paket lämnar enheten. Vilket fel du ser beror på HTTP-biblioteket: ibland ett allmänt nätverksfel, ibland en timeout, ibland ett meddelande som namnger cleartext rakt ut. Vad det aldrig gör är att nå din server. Android dokumenterar standarden och det domänbegränsade alternativet i guiden för säkerhetskonfiguration.
En webbläsare på samma enhet kan fortfarande ladda sidan, och det är ledtråden som de flesta missar. Webbläsare omfattas inte av appens nätverkssäkerhetspolicy.
Varför VPN får skulden
Tre saker ändras oftast samtidigt. Appen kan slå upp ett annat värdnamn efter att VPN anslutits, enheten kan vara ny med en nyare build, eller själva builden kan ha flyttats till en mål-API-nivå som utlöser standarden. VPN är synligt och mål-SDK:n är det inte, så VPN får biljetten.
Jämför målnivåerna för den gamla och den nya builden innan du rör nätverkskonfigurationen. En app som siktar på 27 eller lägre är undantagen, och det förklarar varje rapport av typen «det funkar på min äldre telefon».
Var Expo-flaggan egentligen landar
I ett hanterat Expo-projekt redigerar det inte en Android-manifest att lägga till en inställning i app.json, eftersom prebuild och utvecklingsbuilds är det som producerar manifestet. Det är en konfigurationsplugin som skriver inställningen i det skedet. Den stödda vägen är expo-build-properties, konfigurerad i appkonfigurationen med cleartext-alternativet under android.
{
"plugins": [
["expo-build-properties", {
"android": { "usesCleartextTraffic": true }
}]
]
}Utdraget sätter bara plugin-alternativet; manifestet produceras senare. Kör en prebuild eller en färsk utvecklingsklient-build och granska sedan före omtestning den genererade AndroidManifest.xml avseende android:usesCleartextTraffic, eftersom en omladdning med bara JS behåller det gamla manifestet. Matcha plugin-versionen mot det Expo SDK som projektet körs på. Plugin-alternativ flyttar sig mellan utgåvor, och ett utdrag kopierat från ett annat SDK är en pålitlig källa till tysta no-ops.
Bare-flödet och det snävare alternativet
För bare React Native är motsvarigheten android:usesCleartextTraffic på application-elementet, eller en nätverkssäkerhetskonfiguration som bara tillåter cleartext för namngivna domäner. Den domänbegränsade formen är den man bör föredra, eftersom den tillåter det interna API:et och låter allt annat ligga kvar på HTTPS. Den dokumenterar också sin egen undantagslista, och det är den delen en granskare kommer att fråga om.
Ingen av metoderna ändrar plattformens standard för något du inte har namngett.
Bevisa det först i enhetsloggen
Innan du redigerar konfigurationen, skaffa det exakta felet. adb logcat på en ansluten enhet visar plattformens cleartext-avvisning och namnger komponenten som reste den. En avvisad socket, ett namn som inte går att slå upp eller ett misslyckat TLS-handskakning pekar någon helt annanstans, och att slå på cleartext skulle bara försvaga appen i onödan.
Håll sedan produktionen ärlig. Cleartext är acceptabelt för en laboratorie-endpoint som inte kan erbjuda TLS, och bara under den kortaste tid du kan planera. Om API:et kan avsluta TLS inne i det privata nätet, lägg certifikatet i enhetens förtroendelager och låt cleartext vara avstängt, eftersom tunneln krypterar vägen till sin utgång och ingenting efter.
När endpointen svarar över HTTPS, ta bort behörigheten, bygg om och testa på VPN och på vanligt Wi-Fi i samma session. Namnuppslagning kan skilja sig mellan de två vägarna, och bara paret säger vilken som talar sanning.