From a34c9fd17632852ec1222c38121d280d9c393f26 Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 3 Jun 2026 10:13:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(app):=20=E5=BC=BA=E5=88=B6=20HTTPS=20?= =?UTF-8?q?=E2=80=94=20Android=20=E7=BD=91=E7=BB=9C=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20+=20=E7=94=9F=E4=BA=A7=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=20HTTPS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Android: 添加 network_security_config.xml,默认禁止明文流量 - Android: 仅允许 localhost/127.0.0.1/10.0.2.2 明文(开发调试) - Android: 更新 AndroidManifest 引用网络安全配置 - ApiClient: 默认 URL 改为 https://api.nuanji.app/api/v1 - AppConfig: fromEnvironment 默认值改为 HTTPS 生产地址 - AppConfig: dev 常量保留 localhost(仅用于本地开发) - iOS: ATS 默认已强制 HTTPS,无需修改 审计 ID: 6b-C01 --- app/android/app/src/main/AndroidManifest.xml | 3 ++- .../main/res/xml/network_security_config.xml | 20 ++++++++++++++++++ app/lib/config/app_config.dart | 21 ++++++++++++------- app/lib/data/remote/api_client.dart | 7 ++++++- 4 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 app/android/app/src/main/res/xml/network_security_config.xml diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index 1668f4d..791abdc 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -2,7 +2,8 @@ + android:icon="@mipmap/ic_launcher" + android:networkSecurityConfig="@xml/network_security_config"> + + + + + + + + + + + + localhost + 10.0.2.2 + 127.0.0.1 + + diff --git a/app/lib/config/app_config.dart b/app/lib/config/app_config.dart index ba5f2df..1329350 100644 --- a/app/lib/config/app_config.dart +++ b/app/lib/config/app_config.dart @@ -1,8 +1,12 @@ // 应用环境配置 — 通过 --dart-define 注入 // // 使用方式: -// flutter run --dart-define=API_BASE_URL=http://localhost:3000/api/v1 -// flutter run --dart-define=API_BASE_URL=https://api.nuanji.app/api/v1 +// flutter run # 开发模式(localhost) +// flutter run --dart-define=API_BASE_URL=https://api.nuanji.app/api/v1 # 生产模式 +// +// 安全说明: +// - 生产环境强制 HTTPS(Android network_security_config 禁止明文流量) +// - 开发模式使用 localhost(Android 网络安全配置已允许 localhost 明文) /// 应用环境配置 — 集中管理所有外部服务地址 class AppConfig { @@ -19,19 +23,20 @@ class AppConfig { /// 从编译时环境变量构建配置 /// - /// 使用 `--dart-define` 注入,未设置时使用默认值。 + /// 使用 `--dart-define` 注入,未设置时使用生产 HTTPS 默认值。 + /// 开发环境使用 [dev] 常量或通过 --dart-define 覆盖。 factory AppConfig.fromEnvironment({ - String defaultApiBaseUrl = 'http://localhost:3000/api/v1', - String defaultSseBaseUrl = 'http://localhost:3000/api/v1', + String defaultApiBaseUrl = 'https://api.nuanji.app/api/v1', + String defaultSseBaseUrl = 'https://api.nuanji.app/api/v1', }) { // const String.fromEnvironment 在编译时求值 const apiBaseUrl = String.fromEnvironment( 'API_BASE_URL', - defaultValue: 'http://localhost:3000/api/v1', + defaultValue: 'https://api.nuanji.app/api/v1', ); const sseBaseUrl = String.fromEnvironment( 'SSE_BASE_URL', - defaultValue: 'http://localhost:3000/api/v1', + defaultValue: 'https://api.nuanji.app/api/v1', ); return AppConfig( @@ -40,7 +45,7 @@ class AppConfig { ); } - /// 开发环境默认配置 + /// 开发环境默认配置(localhost 明文 — 仅用于本地调试) static const dev = AppConfig( apiBaseUrl: 'http://localhost:3000/api/v1', sseBaseUrl: 'http://localhost:3000/api/v1', diff --git a/app/lib/data/remote/api_client.dart b/app/lib/data/remote/api_client.dart index 224a402..7c97d41 100644 --- a/app/lib/data/remote/api_client.dart +++ b/app/lib/data/remote/api_client.dart @@ -36,7 +36,12 @@ class ApiClient { /// 是否正在刷新 token(防止并发 401 触发多次刷新) bool _isRefreshing = false; - ApiClient({this.baseUrl = 'http://localhost:3000/api/v1'}) { + /// 创建 API 客户端 + /// + /// [baseUrl] 默认使用 HTTPS 生产地址。 + /// 开发环境可通过构造参数覆盖为 http://localhost:3000/api/v1 + /// (Android 网络安全配置已允许 localhost 明文)。 + ApiClient({this.baseUrl = 'https://api.nuanji.app/api/v1'}) { _dio = Dio(BaseOptions( baseUrl: baseUrl, connectTimeout: const Duration(seconds: 10),