Android 8: открытый HTTP-трафик не разрешен
У меня были сообщения от пользователей с Android 8, что мое приложение (которое использует внутренний канал) не показывает контент. После расследования я обнаружил следующее исключение, происходящее на Android 8:
08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
(Я удалил имя пакета, URL и другие возможные идентификаторы)
На Android 7 и ниже все работает, я не устанавливаю android:usesCleartextTraffic
в манифесте (и установка его на true
не помогает, это значение по умолчанию в любом случае), а также я не использую информацию о сетевой безопасности. Если я позвоню NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()
, это возвращает false
для Android 8, true
для более старой версии, используя тот же файл apk. Я пытался найти упоминание об этом в информации Google об Android O, но безуспешно.
44 ответа
Если вы используете ionic и получаете эту ошибку во время встроенного плагина http, необходимо сделать следующее исправление:
идти к resources/android/xml/network_security_config.xml
Измените его на-
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">api.example.com(to be adjusted)</domain>
</domain-config>
</network-security-config>
Это сработало для меня!
Когда приложение обменивается данными с серверами с использованием сетевого трафика открытого текста, такого как HTTP, это может повысить риск подслушивания и фальсификации содержимого. Третьи лица могут вводить несанкционированные данные или передавать информацию о пользователях. Вот почему разработчикам рекомендуется защищать только трафик, такой как HTTPS.
Но на случай, если использование открытого текста неизбежно, разработчики могут исправить ошибку,
1. Редактирование useCleartextTraffic
атрибут в manifest.xml
файл или
2. Добавление настроек безопасности сети
Опция 1:
В Android 6.0 появился атрибут useCleartextTraffic в элементе приложения в манифесте Android. Значение по умолчанию в Android P: “false”
, Значение true указывает, что приложение намерено использовать чистый сетевой трафик.
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
Вариант 2:
Однако может показаться, что это решает проблему, но это создает угрозу целостности данных. Лучшее решение предлагается в Android 7.0 через файл конфигурации сетевой безопасности. Конфигурация безопасности сети позволяет приложению разрешать трафик открытым текстом из определенного домена.
1) Добавьте файл конфигурации безопасности сети в res/xml.
2) Добавить конфигурацию домена и установить cleartextTrafficPermitted
в “true”
,
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">your_domain.com</domain>
</domain-config>
</network-security-config>
3) Добавьте конфигурацию безопасности вашей сети на ваш Android manifest.xml
файл под заявкой.
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
После изменения API версии 9.0 получение сообщения об ошибке HTTP в открытом виде в YOUR-API.DOMAIN.COM не разрешено (targetSdkVersion="28"). в xamarin, xamarin.android и андроид студии.
Два шага для решения этой ошибки в xamarin, xamarin.android и android studio.
Шаг 1. Создайте файл resources/xml/network_security_config.xml
В network_security_config.xml
<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">mobapi.3detrack.in</domain>
</domain-config>
</network-security-config>
Шаг 2: обновите AndroidManifest.xml -
Добавьте android:networkSecurityConfig="@xml/network_security_config" в тег приложения. например:
<application android:label="your App Name" android:icon="@drawable/icon" android:networkSecurityConfig="@xml/network_security_config">
Добавление этого параметра в заголовок решило мою проблему в apiSauce React Native
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json"
Открытый текст - это любая переданная или сохраненная информация, которая не зашифрована или не предназначена для шифрования.
Когда приложение обменивается данными с серверами, используя сетевой трафик в виде открытого текста, например HTTP (не https), это может повысить риск взлома и подделки контента. Третьи стороны могут вводить неавторизованные данные или утечку информации о пользователях. Вот почему разработчикам рекомендуется использовать только защищенный трафик, например HTTPS. Вот реализация и руководство по решению этой проблемы.
Мы столкнулись с очень похожей проблемой, и нам было сложно ее понять. Для тех незадачливых душ, которым придется с этим столкнуться, вот что мы сделали:
Приложение ionic нормально работало в браузере (Chrome и Firefox), было развернуто в магазине приложений Apple и прекрасно взаимодействовало с нашим API на AWS. Затем мы перешли к сборке Android. В эмуляторе наш запрос https API даже не будет отправлен. На физическом устройстве https-запросы также не будут отправляться (после развертывания для «внутреннего тестирования» в Google Play).
Запустили наше приложение в эмуляторе. Открыл хром, набрал «chrome: // inspect», подождал, щелкнул ссылку на экземпляр эмулятора и смог просмотреть вкладку сети. Запросы будут быстро меняться от (ожидающих) до (отмененных) без отправки на сервер.
Посмотрел весь stackoverflow, и главный совет состоял в том, чтобы отключить https с помощью workaournd cleartextPermitted, что является ужасной идеей.
Другой распространенный совет - использовать собственный http, но какой смысл использовать ionic, если нам нужно иметь 2 базы кода, а я хотел сохранить свои перехватчики http.
Добавлен файл network_security_config.xml (который, вероятно, не является строго необходимым, но удаляет предупреждение о компиляции в Android Studio.)
Проверил SSL-сертификат на наших серверах, щелкнув значок замка в браузере. Выглядело нормально. (возможно, потому, что на самом деле это не так, но у меня было ручное переопределение, которое я давно добавил и забыл). много других преследований за хвостом ...
Наконец, использовал инструмент sslshopper для проверки нашего сертификата SSL: https://www.sslshopper.com/ssl-checker.html
Оказывается, пока наш сертификат был в порядке, цепочка сертификатов - нет . В их диагностике это будет отображаться как красная сломанная стрелка.
По сути, вы должны взять свой сертификат SSL и создать пакет, добавив сертификаты SSL организации, предоставившей ваш сертификат, и добавив любые другие сертификаты SSL, удостоверяющие сертификат, до тех пор, пока вся цепочка не станет чистой. Мы использовали предоставленный комплект, но он недостаточно продвигался по цепочке .
Исправьте цепочку SSL:
cat your-purchased-cert-site-com.crt > your-site.bundle.crt
cat other-org-cert-sectigoRSA-bla-bla-bla.crt >> your-site.bundle.crt
cat another-org-cert-USERTrust-bla-bla-bla.crt >> your-site.bundle.crt
cat some-final-high-level-org-cert.crt >> your-site.bundle.crt
Тогда в нашем случае для nginx на ubuntu:
поместите your-site.bundle.crt туда, где его можно использовать. (в нашем случае / var / ssl)
update /etc/nginx/sites-available/site-name.conf:
ssl_certificate /var/ssl/your-site.bundle.crt
ssl_certificate /var/ssl/your-private-key.key
и перезапустите ваш веб-сервер (в нашем случае nginx: sudo systemctl restart nginx)
проверьте это с помощью программы проверки sslshopper, вы должны полностью увидеть зеленые стрелки.
запустил наш эмулятор, и вызовы API прошли.
Обновление до React Native 0.58.5 или выше. У них есть includeSubdomain
в их конфигурационных файлах в RN 0.58.5.
В 0,58,5 руб. Они объявили network_security_config
с их серверным доменом. Конфигурация безопасности сети позволяет приложению разрешать трафик открытым текстом из определенного домена. Так что нет необходимости прилагать дополнительные усилия, заявив, android:usesCleartextTraffic="true"
в теге приложения вашего файла манифеста. Это будет решено автоматически после обновления версии RN.
Добавь это android:usesCleartextTraffic="true"
в свой файл Androidmanifest.xml внутри тега приложения.
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
...
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
Я сделал все вышеперечисленные ответы, и я пришел с лучшим ответом, я надеюсь, что это может помочь:
В Манифест добавить эти строки:
андроид:networkSecurityConfig="@ XML /network_security_config"
а также
андроид:usesCleartextTraffic="истина"
<application
android:name=".App.Global"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning,InnerclassSeparator"
tools:replace="allowBackup,supportsRtl"
tools:targetApi="n">
А затем в папке res/xml создайте новый файл с именем network_security_config.xml или любым другим!
И добавьте в него следующие строки:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">alibaba.com</domain>
</domain-config>
</network-security-config>
Это происходит из-за вашего протокола домена, http не является безопасным.
Убедитесь, что домен указан правильно в вашем .
В моем случае я использовал команду с
ionic cordova
который изменил домен.
РЕШЕНИЕ 1
Удалить
--external
РЕШЕНИЕ 2
Измените свой домен в
network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">
YOUR_DOMAIN (ex: localhost)
</domain>
</domain-config>
</network-security-config>
У меня была такая же проблема в моем простом приложении для просмотра веб-страниц, потому что мой URL-адрес был http://, но когда вы перешли на https://, ошибка была решена.
Один лайнер для решения вашей проблемы. Я предполагаю, что вы сохраните свой URL-адрес в строке myURL. Добавьте эту строку, и все готово. myURL = myURL.replace("http", "https");