Android 8:不允许Cleartext 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 permittedat 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文件。我试图在谷歌上找到一些关于Android O的信息,但没有成功。

1290001 次浏览

好的,我已经弄清楚了。这是由于Manifest参数android:targetSandboxVersion="2",我添加了这个参数,因为我们也有即时应用程序版本-它应该确保用户从即时应用程序升级到常规应用程序,他不会在传输中丢失数据。然而,正如模糊的描述所暗示的:

指定此应用要使用的目标沙盒。更高版本的沙盒将具有更高的安全级别。

此属性的默认值为1。

它显然还增加了新的安全策略级别,至少在Android 8上是这样。

在AndroidManifet中,我找到了这个参数:

android:networkSecurityConfig="@xml/network_security_config"

@xml/network_security_config在network_security_config.xml定义为:

<?xml version="1.0" encoding="utf-8"?><network-security-config><!--Set application-wide security config using base-config tag.--><base-config cleartextTrafficPermitted="false"/></network-security-config>

只是我改变了cleartextTra的允许为true

根据网络安全配置-

从Android 9(API级别28)开始,明文支持被禁用默认情况下。

再看看Android M和明文流量战争

codelabs解释来自Google

备选案文1-

首先尝试使用https://而不是http://点击URL

备选案文2-

创建文件res/xml/network_security_config.xml-

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">api.example.com(to be adjusted)</domain></domain-config></network-security-config>

AndroidManifest.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>

备选案文3-

android: usesCleartext流量文档

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?><manifest ...><uses-permission android:name="android.permission.INTERNET" /><application...android:usesCleartextTraffic="true"...>...</application></manifest>

正如@刘德华指出的那样,android:targetSandboxVersion也可能是一个问题-

根据清单文档-

android:targetSandboxVersion

此应用程序要使用的目标沙盒。沙盒版本越高数字,安全级别越高。其默认值为1;您也可以将其设置为2。将此属性设置为2会将应用程序切换到不同的SELinux沙盒。以下限制适用于二级沙盒:

  • 网络安全配置中的默认值usesCleartextTraffic为false。
  • 不允许Uid共享。

所以选择4-

如果你有android:targetSandboxVersion<manifest>然后减少到1

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?><manifest android:targetSandboxVersion="1"><uses-permission android:name="android.permission.INTERNET" />...</manifest>
<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain></domain-config></network-security-config>

在上面提供的建议中,我将我的URL提供为http://xyz.abc.com/mno/

我将其更改为xyz.abc.com,然后它开始工作。

它可能对某人有用。

我们最近在Android 9上也遇到了同样的问题,但是我们只需要在WebView中显示一些URL,没有什么特别的。因此,在清单中添加android:usesCleartextTraffic="true"是有效的,但我们不想因此损害整个应用程序的安全性。所以解决方法是将链接从http更改为https

如果可能的话,从#0到#1更改您的网址;

成功了!!!

您可能只想在调试时允许明文,但保留在生产中拒绝明文的安全优势。这对我很有用,因为我在不支持https的开发服务器上测试我的应用程序。以下是如何在生产中强制执行https,但在调试模式下允许明文:

build.gradle:

// Put this in your buildtypes debug section:manifestPlaceholders = [usesCleartextTraffic:"true"]
// Put this in your buildtypes release sectionmanifestPlaceholders = [usesCleartextTraffic:"false"]

在应用程序标签中AndroidManifest.xml

android:usesCleartextTraffic="${usesCleartextTraffic}"

我在android9中的问题是在具有超文本传输协议的域上的webview上导航来自这个答案的解决方案

<applicationandroid:networkSecurityConfig="@xml/network_security_config"...>

和:

res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config></network-security-config>

好吧,这是add it to your Manifest的数千次重复,但基于此的提示,但给你额外福利(也许还有一些背景信息)。


以下解决方案允许您根据环境设置协议(HTTP/HTTPS)。

通过这种方式,您可以将http用于您的开发环境,将https用于您的生产环境,而无需一直更改它!这是必要的,因为通常您没有本地或开发环境的https证书,但它是生产(可能是暂存)环境的必备条件。


Android有一种覆盖src-Directory的功能。

默认情况下,您有

/app/src主要的

但是您可以添加其他目录来覆盖您的AndroidManifest.xml.以下是它的工作原理:

  • 创建目录/app/src/debug
  • 内部创建AndroidManifest.xml

在这个文件中,你不要必须把所有的规则放在里面,但只有你喜欢的规则覆盖从你的 /app/src/主要/AndroidManifest.xml

以下是请求的CLEARTEXT权限的示例:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.yourappname">
<applicationandroid:usesCleartextTraffic="true"android:name=".MainApplication"android:label="@string/app_name"android:icon="@mipmap/ic_launcher"android:allowBackup="false"android:theme="@style/AppTheme"></application>
</manifest>

有了这些知识,现在很容易为1,2,3为您过载您的权限取决于您的调试|主|发布环境。

它的最大好处是……您的生产清单中没有调试内容,并且您保持了一个直接且易于维护的结构

对于React Native项目

它已经固定在RN 0.59上。你可以找到将diff从0.58.6升级到0.59您可以在不升级RN版本的情况下应用它,只需按照以下步骤操作:

创建文件:

android/app/src/debug/res/xml/react_native_config.xml-

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="false">localhost</domain><domain includeSubdomains="false">10.0.2.2</domain><domain includeSubdomains="false">10.0.3.2</domain></domain-config></network-security-config>

Android/app/src/debug/AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application tools:targetApi="28"tools:ignore="GoogleAppIndexingWarning"android:networkSecurityConfig="@xml/react_native_config" /></manifest>

检查接受的答案以了解根本原因。

升级到React Native 0.58.5或更高版本。他们在RN 0.58.5的配置文件中有includeSubdomain

变更日志

在Rn 0.58.5中,他们用他们的服务器域声明了network_security_config。网络安全配置允许应用程序允许来自某个域的明文流量。因此,无需在清单文件的应用程序标记中声明android:usesCleartextTraffic="true"。它将在升级RN版本后自动解决。

要将这些不同的答案应用于Xamarin.Android,您可以使用类和程序集级别属性而不是手动编辑AndroidManifest.xml

当然需要互联网许可(duh…):

[assembly: UsesPermission(Android.Manifest.Permission.Internet)]

注意:通常,程序集级别属性会添加到AssemblyInfo.cs文件中,但using以下和namespace以上的任何文件都可以。

然后在您的Application子类(如果需要,请创建一个)上,您可以添加NetworkSecurityConfig并引用Resources/xml/ZZZZ.xml文件:

#if DEBUG[Application(AllowBackup = false, Debuggable = true, NetworkSecurityConfig = "@xml/network_security_config")]#else[Application(AllowBackup = true, Debuggable = false, NetworkSecurityConfig = "@xml/network_security_config"))]#endifpublic class App : Application{public App(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }public App() { }
public override void OnCreate(){base.OnCreate();}}

Resources/xml文件夹中创建一个文件(如果需要,创建xml文件夹)。

示例xml/network_security_config文件,根据需要进行调整(参见其他答案)

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">www.example.com</domain><domain includeSubdomains="true">notsecure.com</domain><domain includeSubdomains="false">xxx.xxx.xxx</domain></domain-config></network-security-config>

您也可以在ApplicationAttribute上使用UsesCleartextTraffic参数:

#if DEBUG[Application(AllowBackup = false, Debuggable = true, UsesCleartextTraffic = true)]#else[Application(AllowBackup = true, Debuggable = false, UsesCleartextTraffic = true))]#endif

在开发我的应用程序时,我也遇到了同样的“Cleartext HTTP流量不允许”错误。我在我的应用程序中使用RetroFit2进行网络调用,我有两个项目环境(开发和生产)。我的生产域具有带有HTTPS调用的SSL证书,开发不会有https。配置是在构建风格中添加的。但是当我更改为开发时,这个问题会触发。所以我为此添加了下述解决方案。

我在清单上添加了明文通信量

 android:usesCleartextTraffic="true"

然后我在改造配置类OKHttp创建时间中添加了一个连接规范。

 .connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))

完整的OkHttpClient创建如下

OkHttpClient okHttpClient = new OkHttpClient.Builder().readTimeout(10, TimeUnit.SECONDS).connectTimeout(10, TimeUnit.SECONDS).cache(null).connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT)).addInterceptor(new NetworkInterceptor(context)).addInterceptor(createLoggingInterceptor()).addInterceptor(createSessionExpiryInterceptor()).addInterceptor(createContextHeaderInterceptor()).build();

后更改API版本9.0获取错误Cleartext HTTP流量YOUR-API.DOMAIN.COM不允许(目标SdkVersion="28")。

两个步骤来解决这个错误在xamarin,xamarin.android和Android工作室。

步骤1:创建文件资源/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">

在我的情况下,URL在浏览器中也不起作用。

我检查https://www.google.com/

webView.loadUrl("https://www.google.com/")

它为我工作。

在头文件中添加此参数解决了我在apiSauce React Native中的问题

"Content-Type": "application/x-www-form-urlencoded",Accept: "application/json"

只需在AndroidManifest.xml文件中添加android: usesCleartext流量="true"

创建文件-res/xml/network_security.xml

network_security.xml->

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">192.168.0.101</domain></domain-config></network-security-config>

打开AndroidManifests.xml:

 android:usesCleartextTraffic="true" //Add this line in your manifests
<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:usesCleartextTraffic="true"android:theme="@style/AppTheme">

2019年12月更新ionic-4.7.1

<manifest xmlns:tools=“http://schemas.android.com/tools”>
<application android:usesCleartextTraffic=“true” tools:targetApi=“28”>

请在android清单. xml文件中添加上述内容

以前版本的Ionic

  1. 确保您在Ionic项目中的config.xml中包含以下内容:

    <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android"><application android:networkSecurityConfig="@xml/network_security_config" /><application android:usesCleartextTraffic="true" /></edit-config>
  2. Run ionic Cordova build android. It creates Android folder under Platforms

  3. Open Android Studio and open the Android folder present in our projectproject-platforms-android. Leave it for few minutes so that it builds the gradle

  4. After gradle build is finished we get some errors for including minSdVersion in manifest.xml.Now what we do is just remove <uses-sdk android:minSdkVersion="19" /> from manifest.xml.

    Make sure its removed from both the locations:

    1. app → manifests → AndroidManifest.xml.
    2. CordovaLib → manifests → AndroidManifest.xml.

    Now try to build the gradle again and now it builds successfully

  5. Make sure you have the following in Application tag in App → manifest → Androidmanifest.xml:

    <applicationandroid:networkSecurityConfig="@xml/network_security_config"  android:usesCleartextTraffic="true" >
  6. Open network_security_config (app → res → xml → network_security_config.xml).

    Add the following code:

    <?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">xxx.yyyy.com</domain></domain-config></network-security-config>

Here xxx.yyyy.com is the link of your HTTP API. Make sure you don't include any Http before the URL.

Note: Now build the app using Android Studio (Build -- Build Bundle's/APK -- Build APK) and now you can use that App and it works fine in Android Pie. If you try to build app using ionic Cordova build android it overrides all these settings so make sure you use Android Studio to build the Project.

If you have any older versions of app installed, Uninstall them and give a try or else you will be left with some error:

App not Installed

对于安卓手机开发人员,请确保HttpClient实现和SSL/TLS设置为默认值。

它可以在Andorid选项->高级Android选项下找到。

在此处输入图片描述

这样做是出于安全原因,您应该尽可能使用HTTPS(HTTP安全)。
你可以阅读更多关于它这里

这个问题有多种解决方案,具体取决于您的情况。

如果您尝试与第一方服务通信,IE:您自己的Web服务器

服务端:您应该向该服务器添加HTTPS支持并使用HTTPS而不是HTTP。如今,您甚至可以使用LetsEncrypt其他等服务免费做到这一点
客户端:如果你使用的是java.net包中的HttpURLConnection,你可以切换到java.net.ssl包中的HttpsURLConnection,它有一个类似的API,所以切换应该很容易。

如果您使用的是第三方服务,例如Google、Facebook、天气服务等。

如果您正在与之通信的服务支持HTTPS(它很可能支持HTTPS),您可以将请求URL从http://abc.xyz更改为https://abc.xyz

作为最后的手段,如果您要与之通信的第三方服务不支持HTTPS或任何其他形式的安全通信,您可以使用这个答案,但同样,不建议这样做,因为它违背了这个急需的安全功能的目的。

对我来说,有效的答案是@PabloCegarra:

<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config></network-security-config>

您可能会收到有关cleartextTrafficPermitted="true"的安全警告

如果你知道“白名单”的域名,你应该混合接受的答案和上面的答案:

<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="false"><trust-anchors><certificates src="system" /></trust-anchors></base-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">books.google.com</domain><trust-anchors><certificates src="system" /></trust-anchors></domain-config></network-security-config>

此代码适用于我,但我的应用程序只需要从books.google.com检索数据。这样安全警告就消失了。

我已经从已经存在的android清单文件中删除了这一行

 android:networkSecurityConfig="@xml/network_security_config"

并添加

android:usesCleartextTraffic="true"

this in to应用程序标签在清单中

<applicationandroid:usesCleartextTraffic="true"android:allowBackup="true"android:label="@string/app_name"android:largeHeap="true"android:supportsRtl="true"android:theme="@style/AppTheme">

然后这个错误不允许overlay.openstreetmap.nl的明文HTTP流量在android 9和10中为我消失了。我希望这也适用于android 8,如果有帮助,请不要忘记投票谢谢

 cleartext support is disabled by default.Android in 9 and above
Try This one I hope It will work fine
1 Step:->  add inside android build gradle (Module:App)useLibrary 'org.apache.http.legacy'
android {compileSdkVersion 28useLibrary 'org.apache.http.legacy'
}

然后2步:->清单添加清单应用程序标签

<applicationandroid:networkSecurityConfig="@xml/network_security_config">//add drawable goto Step 4
// Step --->3  add to top this line<uses-libraryandroid:name="org.apache.http.legacy"android:required="false" />
</application>

//步骤4-->>创建可绘制的>>Xml文件>>名称为>>network_security_config.xml

   <?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config></network-security-config>

如果您使用离子并在本地超文本传输协议插件期间收到此错误,则需要完成以下修复-

转到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))与服务器通信时,可能会增加黑客攻击和篡改内容的风险。第三方可以注入未经授权的数据或泄露有关用户的信息。这就是为什么鼓励开发人员仅保护流量,例如HTTPS。这里是如何解决这个问题的实现和参考。

Oneliner来解决您的问题。我假设您将把URL存储在myURL字符串中。添加这一行,您就完成了。myURL=myURL.replace("超文本传输协议","https");

尝试使用“https://”而不是“超文本传输协议://”点击URL

我使用Cordov8和cordova-plugin-Whitelist 1.3.4它默认配置我的应用程序没有访问互联网,我只添加一个参数在manifest.xml->Android:使用Cleartext流量="true"

在科尔多瓦8中更改了主节的路径:平台/android/app/src/main/AndroidManifest.xml.

 <?xml version='1.0' encoding='utf-8'?><manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="io.cordova.hellocordova" xmlns:android="http://schemas.android.com/apk/res/android"><supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" /><applicationandroid:hardwareAccelerated="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:usesCleartextTraffic="true"><activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize"><intent-filter android:label="@string/launcher_name"><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /></manifest>

这是一个真正的愚蠢,因为很明显,您的应用程序需要访问互联网。

添加…Android:使用Cleartext流量="true"…您的清单文件似乎可以解决问题,但它会对数据完整性造成威胁。

出于安全原因,我在清单文件中使用清单占位符Android:使用Cleartext流量(如已接受答案的选项3 i. e@Hrishikesh Kadam的响应)以仅允许调试环境上的明文。

在我的build.gradle(: app)文件中,我添加了一个清单占位符,如下所示:

    buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}
debug {manifestPlaceholders.cleartextTrafficPermitted ="true"}}

注意上面这一行的占位符名称允许明文通信量

            manifestPlaceholders.cleartextTrafficPermitted ="true"

然后在我的Android清单中,我使用了相同的占位符…

AndroidManifest.xml-

<?xml version="1.0" encoding="utf-8"?><manifest ...><uses-permission android:name="android.permission.INTERNET" /><application...android:usesCleartextTraffic="${cleartextTrafficPermitted}"...>...</application></manifest>

因此,仅在调试环境下允许明文流量。

简单易行的解决方案[Xamarin表格]

对于Android

  1. 转到Android Project,然后单击Properties

在此处输入图片描述

  1. 打开AssemblyInfo.cs并粘贴此代码:

    [assembly: Application(UsesCleartextTraffic =true)]

在此处输入图片描述

为了iOS

使用NSAppTransportSecurity

在此处输入图片描述

您必须在info.plist文件的NSAppTransportSecurity字典下将NSAllowsArbitraryLoads键设置为YES

<key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict>

Plist配置

将以下内容放入您的resources/android/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true" /></network-security-config>

这解决了科尔多瓦/离子的Android上的Failed to load resource: net::ERR_CLEARTEXT_NOT_PERMITTED问题。

VideoView无法打开此视频在线视频

创建文件res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?><network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config></network-security-config>

申请中的AndroidManifest.xml文件中的新内容:

android:networkSecurityConfig="@xml/network_security_config"
https://techprogrammingideas.blogspot.com/2021/02/android-code-for-displaying-video-with.html
https://youtu.be/90hWWAqfdUU

我有同样的问题在我的简单的webview应用程序,因为我的网址是超文本传输协议://但当你把它变成https://错误得到解决。

我们面临着一个非常相似的问题,弄清楚它是一种痛苦。对于那些不幸的灵魂来说,他们将不得不处理这个问题,以下是我们所做的:

这款ionic应用在浏览器(Chrome和火狐)上运行良好,部署到苹果的应用商店,并且在AWS上与我们的API通信正常。然后我们进行了Android版本。在模拟器中,我们的https API请求甚至不会被发送出去。在物理设备上,https请求也不会被发送出去(部署到Google Play的“内部测试”后)

在模拟器中运行我们的应用程序打开chrome,输入“chrome://检查”,等待,单击模拟器实例的链接,并且能够查看网络选项卡。请求将快速从(挂起)循环到(取消),而不会发送到服务器。

查看了整个stackoverflow,主要建议是使用cleartextPer的workaournd禁用https,这是一个可怕的想法。

另一个常见的建议是使用原生超文本传输协议,但是如果我们必须有两个代码库,那么使用ionic有什么意义,我想保留我的超文本传输协议拦截器。

添加了一个network_security_config.xml文件(这可能不是绝对必要的,但它删除了Android Studio中的编译警告。

通过单击浏览器中的锁定图标来检查我们服务器上的SSL证书。看起来不错。(也许是因为它真的不是,但我有一个手动覆盖,我很久以前就添加了,忘记了)。很多其他的追尾……

最后使用sslshop的工具来验证我们的SSL证书:https://www.sslshopper.com/ssl-checker.html

事实证明,虽然我们的证书没问题,但证书链却不太好。这将在他们的诊断中显示为红色的破碎箭头。

基本上,您必须获取您的SSL证书并创建一个捆绑包,方法是附加提供您证书的组织的SSL证书,并附加任何其他认证认证者的SSL证书,直到整个链干净为止。我们使用了提供的捆绑包,但它并没有充分通过链条

修复SSL链:

cat your-purchased-cert-site-com.crt > your-site.bundle.crtcat other-org-cert-sectigoRSA-bla-bla-bla.crt >> your-site.bundle.crtcat another-org-cert-USERTrust-bla-bla-bla.crt >> your-site.bundle.crtcat some-final-high-level-org-cert.crt >> your-site.bundle.crt

然后,在我们的例子中,对于ubuntu上的nginx:

把your-site.bundle.crt放在可以使用的地方(在我们的例子中, /var/ssl)

update /etc/nginx/sites-available/site-name.conf:ssl_certificate /var/ssl/your-site.bundle.crtssl_certificate /var/ssl/your-private-key.key

并重新启动您的Web服务器(在我们的例子中是nginx: sudo system ctl restart nginx)

用sslshop的检查器检查它,你应该一路看到绿色箭头。

启动我们的模拟器,API调用直接通过。

检查域名是否在您的network_security_config.xml中正确。

在我的例子中,我使用了一个命令--externalionic 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>

我建议同时添加dev和prod网络配置:

添加res/xml/network_security_config_dev.xml

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="true"><domain includeSubdomains="true">10.0.2.2</domain></domain-config></network-security-config>

添加res/xml/network_security_config_prod.xml

<?xml version="1.0" encoding="utf-8"?><network-security-config><domain-config cleartextTrafficPermitted="false"><domain includeSubdomains="true">yourdomain.com</domain></domain-config></network-security-config>

在Gradle脚本下(在android Studio中),找到build.gradleandroid.app)并查找代码类型发布调试(如果不存在则创建):

buildTypes {
release {minifyEnabled falsemanifestPlaceholders.securityConfig = "@xml/network_security_config_prod"}
debug {manifestPlaceholders.securityConfig = "@xml/network_security_config_dev"}
}

在AndroidManifest.xml使用安全配置参数。占位符如下(在build.gradle中定义):

<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:networkSecurityConfig="${securityConfig}"   <------- here