S3 TLS 默认关闭与清除 App 数据行为

December 14, 2025
3 min read
By devshan

Table of Contents

This is a list of all the sections in this post. Click on any of them to jump to that section.

背景

  • 项目已经是端到端加密:
    • 客户端在本地用 AES-256-GCM 加密后,才上传到 S3。
    • S3 只看到密文,传输层即使被窃听也无法解开。
  • 这种场景下,TLS 的价值更多是“防止元数据泄露”和“防劫持”,但在可信局域网或自建环境中,优先级可以适当降低。
  • 我这边的诉求:
    • 默认尽量追求传输简单和性能优先。
    • 不希望一装就默认开 TLS,尤其是在 MinIO 这种常见的非 TLS 配置下。
  • 另外,设置中提供了“清除所有应用数据”操作,直觉上应该把包括 S3 TLS 开关在内的所有偏好一起恢复为默认。

本次调整围绕两个问题:

  1. S3 useSsl 的默认值与加载逻辑。
  2. “清除所有应用数据”是否真的把 TLS 开关恢复为默认关闭。

客户端 S3 TLS 默认值

偏好加载逻辑

  • 所有偏好在 AppState._loadPreferences 中加载:
    • 位置:client/lib/core/state/app_state.dart:133-151
    • 与 S3 相关的字段:
      • _s3Endpoint = prefs.getString('s3_endpoint');
      • _s3AccessKey = prefs.getString('s3_access_key');
      • _s3SecretKey = prefs.getString('s3_secret_key');
      • _s3Bucket = prefs.getString('s3_bucket');
      • _s3UseSsl = prefs.getBool('s3_use_ssl') ?? false;
  • 关键在最后一行:
    • 如果本地偏好里还没有 s3_use_ssl 这个 key,则使用 false 作为默认值。
    • 这保证了“新装应用”或者“从未修改过 TLS 设置”的情况下,TLS 是关闭的。

对外暴露与修改

  • 对外 getter:bool get s3UseSsl => _s3UseSsl;client/lib/core/state/app_state.dart:221-243
  • 修改方法:Future<void> setS3UseSsl(bool value)client/lib/core/state/app_state.dart:339-345
    • 直接更新内存中的 _s3UseSsl
    • 将值写入 SharedPreferencess3_use_ssl
    • 触发 notifyListeners()
  • 设置页中的 UI 开关:
    • 位于 S3 配置弹窗的 SwitchListTile
      • client/lib/ui/settings_page.dart:169-243
    • 初始值取自 appState.s3UseSsl
    • 副标题文案明确:“默认关闭,以提升传输速度”。

与后端默认值的对应

  • Go 核心的默认配置同样是 UseSSL: false
    • core/internal/config/config.go:27-46
    • DefaultConfig().S3.UseSSL 被设置为 false
  • 这意味着:
    • 如果客户端不显式要求启用 TLS,后端默认也是以非 TLS 端点工作(通常是 MinIO 的 http://host:9000)。
    • 前后端在“默认关闭 TLS”这个点上保持一致。

清除 App 数据后的 TLS 行为

清除入口与调用链

  • 设置页面的“清除所有应用数据”:
    • UI 入口:client/lib/ui/settings_page.dart:361-409
    • 点击后弹出二次确认,对话内容明确说明只清除本地数据,不动服务器文件。
    • 确认后执行:
      • await appState.clearAllAppData();
      • await ThumbnailCacheManager().clearAllThumbnails();
      • 重置本地一些 UI 状态,并重启到 HomePage

clearAllAppData 的具体行为

  • 方法定义:client/lib/core/state/app_state.dart:1400-1444
  • 做的事情包括:
    • 清空 SharedPreferencesawait prefs.clear();
    • 清除本地数据库中的所有文件元数据、下载任务、传输记录与 app 配置。
    • 重置内存中的状态为“初始值”,例如:
      • _isInitialized = false;
      • _isUnlocked = false;
      • _currentPath = '/';
      • _files = [];
      • _uploadConcurrency = 3;
      • _downloadConcurrency = 3;
      • _sortField = FileSortField.name;
      • _sortDirection = FileSortDirection.asc;
      • _s3Endpoint = null;
      • _s3AccessKey = null;
      • _s3SecretKey = null;
      • _s3Bucket = null;
      • _s3UseSsl = false;
      • _appPinCode = null;
      • _appPinRequired = false;
      • _themeMode = ThemeMode.system;
    • 清空 API 的认证 token:api.clearAuthToken();
  • 注意 _s3UseSsl = false; 这一行:
    • 即使之前手动打开了 TLS 开关,clearAllAppData 之后也会把它显式改回 false
    • 再加上 SharedPreferences 全量 clear(),下次启动 _loadPreferences 时,也会重新走默认的 ?? false

曾经遇到的困惑

  • 开发过程中曾出现过一种错觉:
    • 点击“清除应用数据”后,重新打开设置页,发现 TLS 开关“看起来还是开着”。
    • 实际原因往往是:
      • UI 没有及时刷新,或者旧的 AppState 实例仍然在内存里。
      • 没有完整走完“清除 → 重建 AppState → 重新加载偏好”的链路。
  • 经检查 clearAllAppData 代码和实际运行行为后确认:
    • 从持久化角度看,TLS 状态已经被重置为默认关闭。
    • 改完后,只要重新启动应用或完整走一遍 HomePage 构建流程,界面上的开关就会与真实状态对齐。

总结

  • 默认行为:
    • 客户端和后端的 S3 TLS 默认值都是 false
    • 新安装或从未配置过的情况下,都是以非 TLS 方式访问 S3。
  • 配置行为:
    • 可以在 S3 配置弹窗中显式打开“使用 HTTPS”。
    • 该选项会写入本地偏好,并通过 AppState 的 getter 驱动 UI 展示。
  • 清理行为:
    • “清除所有应用数据”会:
      • 清空所有偏好(包括 S3 TLS 设置)。
      • 把内存中的 _s3UseSsl 重置为 false
    • 只要重新进入应用主流程,TLS 开关会正确回到“关闭”状态。
  • 整体上一致遵循了一个简单的原则:
    • 端到端加密已经保证数据安全,TLS 默认为关闭,有需要时手动开启。