Je hebt een nieuwe build uitgebracht, bent naar de VPN overgestapt, en hetzelfde scherm laadde niet meer. Op Android 9 en hoger is de meest voorkomende verklaring saaier: het platform weigert gewone HTTP voor apps die op API 28 of hoger richten, en de VPN veranderde net genoeg context om dat te onthullen. De fout die je ziet hangt af van de HTTP-client, daarom zegt die zo zelden cleartext.

Wat de fout eigenlijk is

Vanaf Android 9 blokkeert het platform cleartext standaard zodra een app op API-niveau 28 of hoger richt. Het verzoek naar een gewoon HTTP-adres wordt door het platform geweigerd voordat er ook maar één pakketje het apparaat verlaat. Welke fout je ziet hangt af van de HTTP-bibliotheek: soms een algemene netwerkfout, soms een time-out, soms een bericht dat cleartext ronduit noemt. Wat het nooit doet, is je server bereiken. Android documenteert de standaard en het domeingebonden alternatief in de gids voor beveiligingsconfiguratie.

Een browser op hetzelfde apparaat kan de pagina nog steeds laden, en dat is de aanwijzing die de meeste mensen missen. Browsers vallen niet onder het netwerkbeveiligingsbeleid van je app.

Waarom de VPN de schuld krijgt

Meestal veranderen er drie dingen tegelijk. De app kan na het verbinden van de VPN een andere hostnaam oplossen, het apparaat kan nieuw zijn met een nieuwere build, of de build zelf kan naar een doel-API-niveau zijn verschoven dat de standaard activeert. De VPN is zichtbaar en de doel-SDK niet, dus krijgt de VPN het ticket.

Vergelijk de doelniveaus van de oude en nieuwe build voordat je de netwerkconfiguratie aanraakt. Een app die op 27 of lager richt, is vrijgesteld, en dat verklaart elk rapport van het type «bij mij werkt het op mijn oudere telefoon».

Waar de Expo-vlag echt landt

In een beheerd Expo-project bewerkt het toevoegen van een instelling aan app.json geen Android-manifest, omdat prebuild en development-builds het manifest produceren. Een configuratieplugin is wat de instelling in die fase schrijft. De ondersteunde route is expo-build-properties, geconfigureerd in de app-configuratie met de cleartext-optie onder android.

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

Het fragment stelt alleen de plugin-optie in; het manifest wordt later geproduceerd. Voer een prebuild of een verse development-client-build uit en bekijk dan vóór het opnieuw testen de gegenereerde AndroidManifest.xml op android:usesCleartextTraffic, want een herlaad met alleen JS houdt het oude manifest. Stem de plugin-versie af op de Expo SDK waarop het project draait. Plugin-opties verschuiven tussen releases, en een fragment dat uit een andere SDK is gekopieerd, is een betrouwbare bron van stille no-ops.

De bare-workflow en de smallere optie

Voor bare React Native is het equivalent android:usesCleartextTraffic op het application-element, of een netwerkbeveiligingsconfiguratie die cleartext alleen voor genoemde domeinen toestaat. De domeingebonden vorm heeft de voorkeur, omdat die de interne API toestaat en al het andere op HTTPS laat. Hij documenteert ook zijn eigen uitzonderingenlijst, en dat is het deel waar een reviewer naar zal vragen.

Geen van beide benaderingen verandert de standaard van het platform voor iets dat je niet hebt genoemd.

Bewijs het eerst uit de apparaatlog

Voordat je de configuratie bewerkt, haal de exacte fout op. adb logcat op een aangesloten apparaat toont de cleartext-weigering van het platform en noemt de component die hem veroorzaakte. Een geweigerde socket, een naam die niet oplost of een mislukte TLS-handshake wijzen ergens anders heen, en cleartext aanzetten zou de app alleen maar onnodig verzwakken.

Houd de productie daarna eerlijk. Cleartext is acceptabel voor een lab-endpoint dat geen TLS kan bieden, en alleen voor de kortste tijd die je kunt plannen. Als de API TLS binnen het privénetwerk kan beëindigen, zet het certificaat dan in de trust store van het apparaat en laat cleartext uitgeschakeld, want de tunnel versleutelt de weg naar zijn uitgang en niets daarna.

Zodra het endpoint over HTTPS antwoordt, verwijder je de toestemming, bouw je opnieuw en test je op de VPN en op gewoon Wi-Fi in dezelfde sessie. Naamresolutie kan tussen die twee routes verschillen, en alleen het paar vertelt je welke de waarheid spreekt.

Gerelateerde artikelen