【Flutter】iOS 网络权限设置 ② ( 配置 iOS 平台可使用 HTTP 访问 | ATS 网络安全强制规范 )

文章目录

  • 前言
  • [一、iOS ATS 机制概述](#一、iOS ATS 机制概述)
  • 二、配置操作步骤与方案详解
    • [1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 )](#1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 ))
      • 操作步骤
      • [Xcode 可视化操作对应项](#Xcode 可视化操作对应项)
    • [2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 )](#2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 ))
    • [3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 )](#3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 ))
    • [4、商业环境 : 多环境配置封装案例](#4、商业环境 : 多环境配置封装案例)
      • 实现思路
      • [Debug 环境完整配置示例](#Debug 环境完整配置示例)
      • [Release 环境完整配置示例](#Release 环境完整配置示例)
      • 生效验证
  • 三、注意事项与常见坑点排查
    • [1、IP 地址配置的兼容性问题](#1、IP 地址配置的兼容性问题)
    • 2、配置修改后不生效
    • 3、常见报错与处理方案
      • [报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.](#报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.)
      • [报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常](#报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常)
      • [报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题](#报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题)
    • 4、安全规范建议
  • 总结

参考文档 :

前言

在 移动应用 安全规范 不断收紧 的背景下 , 苹果自 iOS 9 系统起引入了 App Transport Security ( ATS , 应用传输安全 ) 机制 , 默认强制所有应用的网络请求必须使用 HTTPS 加密传输 , 直接拦截所有 HTTP 明文请求 ;

在 Flutter 跨平台开发场景中 , Android 平台默认允许 HTTP 请求 , 而 iOS 侧会因 ATS 规则导致 HTTP 接口直接请求失败 , 尤其在以下场景中配置需求十分普遍 :

  • 本地开发调试阶段 , 连接局域网内的后端测试服务
  • 对接企业内部历史系统 , 暂未完成 HTTPS 升级
  • 模拟器本地联调 localhost 接口
  • 部分公网第三方接口仅提供 HTTP 协议

本文将从 ATS 原理出发 , 详细讲解 Flutter iOS 端 HTTP 访问的多种配置方案、多环境商业项目封装实践 , 以及开发过程中的常见坑点与排查方案 ;


一、iOS ATS 机制概述


1、简介

ATS ( App Transport Security ) 是苹果系统内置的网络安全强制规范 , 作用于应用的所有网络请求底层 ;

Flutter 的 diohttp 等网络库最终均 调用 iOS 原生 URLSession 能力 , 因此同样受 ATS 约束 , 其默认规则为 :

  • 所有网络请求必须使用 HTTPS 协议
  • 服务端 TLS 版本不低于 1.2
  • 证书必须符合苹果安全标准

未满足条件的 HTTP 明文请求会被系统直接拦截 , 抛出网络错误 , 无法正常请求数据 ;

2、核心原理

ATS 运行在 iOS 系统网络层 , 而非应用代码层 , 因此 仅修改 Flutter 端的网络请求代码无法绕过限制 ;

必须通过修改 iOS 工程的 Info.plist 配置文件 , 向系统声明 " 允许例外的域名/场景 " , 才能放行对应的 HTTP 请求 ;

苹果提供了三种层级的例外配置 , 安全等级从高到低分别为 : 指定域名例外 > 本地网络例外 > 全局放开例外 , 其中 全局放开方案在 App Store 审核中会被严格拦截 , 仅可用于本地开发 ;

二、配置操作步骤与方案详解


所有配置均需修改 iOS 工程下的 ios/Runner/Info.plist 文件 , 提供 " Xcode 可视化编辑 " 和 " 直接文本编辑 " 两种操作方式 , 以下分别讲解三种主流配置方案 ;

1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 )

该方案仅对指定的域名放开 HTTP 权限 , 其余域名仍遵循 ATS 安全规则 , 符合苹果审核规范 , 是生产环境的唯一合规方案 ;

操作步骤

操作步骤 :

  1. 打开配置文件 : 打开 Flutter 项目 , 定位到 ios/Runner/Info.plist 文件
  2. 选择编辑方式 :
    • 方式 A 可视化编辑 : 右键用 Xcode 打开 Runner.xcworkspace , 在左侧项目导航中找到 Info.plist 进行可视化编辑
    • 方式 B 修改配置文件 : 直接在 VS Code 中以文本/XML 形式打开 Info.plist
  3. 在根 <dict> 标签内添加 ATS 配置 , 写入需要放行的域名 :

ios/Runner/Info.plist 添加配置示例 :

xml 复制代码
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 )  -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <!-- 替换为你的正式接口域名 , 无需添加 http:// 前缀 -->
        <key>api.yourcompany.com</key>
        <dict>
            <!-- 允许该域名的所有子域名生效 , 如 v1.api.yourcompany.com -->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!-- 允许该域名使用 HTTP 明文请求 -->
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 )  -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>

Xcode 可视化操作对应项

  • 添加 App Transport Security Settings ( 类型为 Dictionary )
  • 其子项添加 Exception Domains ( 类型为 Dictionary )
  • Exception Domains 下添加域名作为 Key , 类型为 Dictionary
  • 域名下添加 NSIncludesSubdomains = YES、NSExceptionAllowsInsecureHTTPLoads = YES

2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 )

该方案专门放开 localhost、局域网 IP、.local 域名的 HTTP 权限 , 不会影响公网请求的安全规则 , 苹果审核允许该配置 , 是本地开发调试的最优解 ;

适用场景

  • 模拟器连接本地电脑运行的后端服务
  • 真机连接同一 WiFi 下的测试服务器 ( 192.168.x.x 等局域网 IP )
  • 开发阶段需要频繁切换测试地址

ios/Runner/Info.plist 添加配置示例 :

xml 复制代码
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 )  -->
<key>NSAppTransportSecurity</key>
<dict>
    <!-- 放行所有本地局域网、localhost 的 HTTP 请求 -->
    <key>NSAllowsLocalNetworking</key>
    <true/>
    
    <!-- 可同时叠加正式域名例外 , 两者不冲突 -->
    <key>NSExceptionDomains</key>
    <dict>
        <key>test-api.yourcompany.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 )  -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>

3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 )

该方案完全关闭 ATS 安全校验 , 允许所有 HTTP、HTTPS 请求 , 风险极高 , 提交 App Store 审核会直接被驳回 , 仅可用于纯本地开发、快速验证场景 ;

ios/Runner/Info.plist 添加配置示例 :

xml 复制代码
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 )  -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 )  -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>

⚠️ 重要警告 : 正式打 Release 包、提交 App Store 时必须移除该配置 , 否则审核会被直接驳回 ;

4、商业环境 : 多环境配置封装案例

在企业级 Flutter 项目中 , 通常存在 Debug、Test、Release 多套环境 , 不同环境对 HTTP 的权限需求不同 ;

可通过 Xcode 构建配置分离 , 实现不同打包环境自动对应不同 ATS 规则 , 避免人工修改出错 ;

实现思路

  1. 在 Xcode 中为 Debug、Release 分别创建对应的 Info-Debug.plistInfo-Release.plist 文件
  2. Debug 配置 : 包含 NSAllowsLocalNetworking + 测试域名例外
  3. Release 配置 : 仅保留正式域名例外 , 移除所有调试相关配置
  4. 在 Xcode 的 Build Settings 中 , 为不同 Configuration 指定对应的 Info.plist 文件

Debug 环境完整配置示例

ios/Runner/Info.plist 添加配置示例 :

xml 复制代码
<!-- Info-Debug.plist 节选 -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>test-api.yourcompany.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
        <key>pre-api.yourcompany.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 )  -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>

Release 环境完整配置示例

ios/Runner/Info.plist 添加配置示例 :

xml 复制代码
<!-- Info-Release.plist 节选 -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>api.yourcompany.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

生效验证

修改完成后执行以下命令 , 清理缓存并重新运行 , 确保配置生效 :

shell 复制代码
flutter clean
cd ios && pod install && cd ..
flutter run

三、注意事项与常见坑点排查


1、IP 地址配置的兼容性问题

很多开发者会直接将 IP 地址写入 NSExceptionDomains , 该写法存在系统版本限制 :

  • iOS 17 /iPadOS 17 及以上 : 官方支持直接将 IPv4/IPv6 地址、CIDR 网段作为 NSExceptionDomains 的 Key
  • iOS 16 及更早版本 : NSExceptionDomains 仅识别域名 , 直接写 IP 完全不生效 , 请求仍会被 ATS 拦截

通用解决方案 : 调试阶段统一使用 NSAllowsLocalNetworking 放行局域网 IP , 无需单独写 IP 条目 , 可兼容全系统版本 ;

2、配置修改后不生效

这是最高频的踩坑场景 , 按以下步骤依次排查 :

  1. 未停止旧的 Flutter 进程 : 必须终止 flutter run 后重新运行 , 热重载不会更新 Info.plist 配置
  2. 未清理构建缓存 : 执行 flutter clean + pod install 后重新构建
  3. 设备 / 模拟器残留旧包 : 卸载应用后重新安装 , 旧包的配置会存在系统缓存
  4. 配置位置错误 : 必须放在 Info.plist 根层级的 `` 标签内 , 不可嵌套在其他节点下

3、常见报错与处理方案

报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

  • 原因 : ATS 拦截了 HTTP 明文请求
  • 解决方案 : 根据业务场景选择上文三种方案之一 , 添加对应例外配置

报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常

  • 原因 : iOS 14+ 真机访问本地网络需要用户授权 , 未添加权限描述会导致连接失败
  • 解决方案 : 在 Info.plist 中添加 NSLocalNetworkUsageDescription 权限说明字段

报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题

  • 原因 : 使用了 NSAllowsArbitraryLoads = true 全局放开配置
  • 解决方案 : 移除全局配置 , 改为仅对必要域名添加例外规则

4、安全规范建议

  • 生产环境必须使用 " 指定域名例外 " 方案 , 禁止全局放开 ATS
  • 优先推动后端服务升级 HTTPS , ATS 例外仅作为过渡方案使用
  • 测试 / 开发环境的宽松配置 , 严禁带入正式打包脚本
  • 定期清理不再使用的例外域名 , 缩小安全攻击面

总结

本文完整讲解了 Flutter iOS 端配置 HTTP 访问的全流程方案 , 核心要点总结如下 :

  1. 底层机制 : iOS ATS 为系统级网络安全规则 , 会拦截所有 HTTP 明文请求 , 必须通过 Info.plist 配置例外才能放行

  2. 三种配置方案 :

    • 指定域名例外 : 生产环境唯一合规方案 , 安全可控且可正常上架
    • 本地局域网放行 : 开发调试首选 , 兼顾便利与安全 , 符合审核规范
    • 全局放开 : 仅本地临时调试使用 , 正式包严禁使用 , 上架必被驳回
  3. IP 配置限制 : iOS 16 及以下不支持 IP 作为例外域名 , 推荐用 NSAllowsLocalNetworking 兼容全系统版本

  4. 商业项目实践 : 通过多环境 Info.plist 分离 , 实现开发 / 生产配置自动隔离 , 避免人工配置失误

  5. 常见问题 : 配置不生效优先检查缓存、旧包、权限描述;上架被拒优先排查全局放开配置

整体遵循 " 最小权限原则 " , 仅对必要的域名放开 HTTP 权限 , 优先推进 HTTPS 升级 , 才能同时满足开发效率、应用安全与审核合规的需求 ;

相关推荐
tiantianuser1 小时前
NVME-oF IP 设计1 :为什么要设计它?
网络·网络协议·rdma·roce v2·nvme of
笨鸟先飞的橘猫1 小时前
skynet——网络模块学习
网络·学习·skynet
xd1855785551 小时前
鸿蒙PC平台Flutter魔术教学应用开发实践:打造跨端沉浸式魔术学习体验
人工智能·学习·flutter·华为·harmonyos·鸿蒙
恋猫de小郭1 小时前
Flutter Windows 开始支持 Impeller ,还修复了多窗口 bug
android·前端·flutter
kyle~1 小时前
Linux---Snap(隔离式Linux 软件分发范式)
linux·运维·网络
pt10432 小时前
思科网络自动化入门课程介绍
运维·网络·自动化
CHENKONG_CK11 小时前
晨控CK-FR102ANS-EIP与基恩士KVX520系列PLC配置EtherNet/IP通讯连接手册
网络
草根站起来12 小时前
“双算法SSL证书”伪方案、国产SSL证书营销话术与等保绑定乱象批判
网络·网络协议·ssl
Bobolink_13 小时前
跨境业务网络环境评估,“干净、一致、独享”三个关键指标
开发语言·网络·php·跨境网络·网络环境