2997 字
15 分钟

OSS Hub:为什么要做一个统一对象存储管理平台

OSS Hub:为什么要做一个统一对象存储管理平台#

对象存储很适合放图片、视频、构建产物、配置文件和归档数据,但云厂商控制台通常更偏向基础设施管理,而不是团队日常使用。

当 Bucket 数量逐渐增加,实际遇到的问题往往不再是“能不能上传”,而是:

  • 文件分散在不同云厂商和不同 Bucket 中,需要频繁切换控制台。
  • 对象只能按 Key 浏览,缺少面向业务的搜索、标签和最近上传记录。
  • 团队成员不适合直接持有 AccessKey,也不应该拥有整个云账号的权限。
  • 浏览器上传、大文件分片、预览、下载和 CORS 配置需要每个项目重复实现。
  • 文件可能被其它程序写入、覆盖或删除,数据库记录和远端对象会逐渐产生偏差。
  • 阿里云 OSS 与 S3 兼容服务的 SDK、签名方式和扩展能力并不完全一致。

OSS Hub 就是在这个背景下产生的。它的目标是在对象存储之上增加一层统一的业务管理能力,同时保持文件内容仍然由对象存储承载。

文章结构#

这个系列包含四篇文章:

  • 本文:项目目的、使用场景、整体架构、核心模块和数据模型。
  • 后端篇:认证权限、多云适配、文件浏览、直传、分片上传、标签和数据对账。
  • 前端篇:桌面端与移动端、文件工作台、上传队列、预览和实际演示流程。
  • 部署篇:初始化、生产构建、SQLite/PostgreSQL、OpenAPI、测试和后续演进。

项目定位#

OSS Hub 是一个前后端一体的对象存储资源管理后台。

它不替代对象存储,而是把对象存储原本偏底层的 API 整理成团队可以直接使用的产品能力:

  • 在一个界面中管理多套云存储配置。
  • 使用统一方式接入阿里云 OSS 和 S3 兼容服务。
  • 按目录实时浏览远端对象,并通过数据库索引完成搜索和标签筛选。
  • 使用浏览器预签名直传,避免文件内容经过业务服务器。
  • 对大文件执行可恢复的分片上传。
  • 按云存储划分团队与读写权限。
  • 发现对象存储与数据库之间的缺失、变化和未登记对象。
  • 提供 Bucket 生命周期、防盗链和 CORS 管理入口。

适合的使用场景包括:

  • 企业或小团队内部文件中心。
  • 图片、视频、RAW 文件等媒体素材管理。
  • 构建产物、安装包、日志和配置文件管理。
  • 多云对象存储统一入口。
  • 需要定期核对远端对象和业务索引的数据管理系统。

项目目标#

这个项目的目标可以分为五层。

第一层:统一入口#

用户不需要记住不同云厂商控制台、Region、Bucket 和 Endpoint,只需要登录 OSS Hub,再从顶部选择当前云存储。

文件浏览、搜索、上传、标签和管理页面会自动切换到当前 Bucket。没有访问权限的云存储不会出现在选择器中。

OSS Hub 概览工作台(待补图)

第二层:保护云凭据#

AccessKey 只保存在后端,并使用独立配置密钥加密入库。前端不会拿到明文 AK/SK。

上传时,后端根据用户权限、目标路径、文件类型和上传参数生成短期预签名 URL;浏览器只使用这个 URL 把文件直接写入对象存储。

第三层:增加业务索引#

对象存储擅长按 Key 读取对象,但不擅长复杂业务查询。OSS Hub 使用数据库维护文件索引,从而支持:

  • 按原始文件名、存储文件名和 ObjectKey 搜索。
  • 按路径前缀限定范围。
  • 按多个标签组合筛选。
  • 展示最近上传文件。
  • 保存图片元数据、上传人和操作状态。

数据库不是远端对象的替代品,而是一个面向业务查询的索引层。

第四层:建立权限边界#

系统把权限分为平台权限和云存储权限:

  • admin:全局超级权限。
  • oss-hub.admin:OSS Hub 平台管理员。
  • oss-hub.user:允许登录平台。
  • storage.<key>.admin:管理指定云存储。
  • storage.<key>.read:只读访问指定云存储。

这种模型让一个用户可以管理 A Bucket、只读 B Bucket,同时完全看不到 C Bucket。

第五层:处理数据偏差#

真实系统中,对象不一定全部由 OSS Hub 创建。CI、脚本、云控制台或其它应用都可能直接操作 Bucket。

因此系统必须同时回答三个问题:

  1. 远端存在、数据库也存在,内容是否发生变化?
  2. 数据库存在、远端不存在,是否需要清理索引?
  3. 远端存在、数据库不存在,是否需要导入登记?

OSS Hub 通过分步扫描、问题记录、重新检查、导入和清理操作完成这个闭环。

整体架构#

项目采用 npm workspaces 管理前后端:

oss-hub/
├── backend/ # Fastify + TypeScript + Prisma
├── frontend/ # Vue 3 + Vite + Pinia
├── docs/ # 产品、API、部署和接入文档
├── scripts/ # 构建、迁移、OpenAPI 和生产准备脚本
├── test/ # 后端、前端与 Playwright 测试
└── package.json # workspace 与统一命令

运行时由四个部分组成:

flowchart LR U[浏览器用户] --> F[Vue 管理后台] F -->|Bearer Token + JSON API| B[Fastify 后端] F -->|预签名 PUT / UploadPart| O[对象存储] B -->|SDK 管理请求| O B -->|业务索引与配置| D[(SQLite / PostgreSQL)] B -->|JWT / JWKS 验证| S[外部 SSO]

这里最重要的设计是:

  • 控制请求经过后端。
  • 文件内容尽量由浏览器直接传到对象存储。
  • 数据库保存管理信息和搜索索引。
  • 对象存储仍然是文件内容的最终事实来源。

技术栈#

后端主要使用:

  • Node.js + TypeScript。
  • Fastify 5。
  • Prisma 6。
  • SQLite,另有 PostgreSQL schema 和迁移脚本。
  • ali-oss 与 AWS SDK v3。
  • jose 负责 JWT、JWKS 和本地 token。
  • Zod 负责输入校验。
  • archiver 负责批量归档下载。
  • exifr 负责图片元数据读取。

前端主要使用:

  • Vue 3。
  • Vite 6。
  • Pinia。
  • Vue Router。
  • Tailwind CSS。
  • Axios。
  • CodeMirror,用于 JSON 等文本内容的只读展示。
  • lucide-vue-next 图标。

核心模块#

认证与用户#

OSS Hub 支持三种认证模式:

  • sso:只使用外部 OAuth/OIDC。
  • local:只使用内置用户名和密码。
  • both:同时提供两种登录方式。

外部 token 通过 JWT/JWKS 验证,SSO 用户第一次进入系统时会同步成本地用户记录。内置账号则由后端签发本地 JWT。

云存储配置#

每条云存储配置包含:

  • 唯一 Key 和显示名称。
  • 云服务商类型。
  • SDK 协议:阿里云 OSS 或 S3。
  • Region、Bucket、Endpoint、公共访问域名。
  • 加密后的访问凭据。
  • 上传重命名、覆盖策略和命名模板。
  • 不登记路径前缀。

云厂商分类用于界面展示,真正决定后端实现的是 SDK 协议。

OSS Hub 云存储配置(待补图)

文件与目录#

文件页面按对象 Key 的前缀和分隔符实时浏览 Bucket。目录并不是数据库中的实体,而是对象 Key 形成的逻辑层级。

系统同时显示:

  • 已登记文件:远端存在,数据库中也有 FileObject
  • 未登记对象:远端存在,但数据库中还没有索引。
  • 逻辑文件夹:由公共前缀产生。

搜索与标签#

搜索读取数据库索引,而不是扫描整个 Bucket。标签又分为两类:

  • 系统标签:保存在 OSS Hub 数据库中,适合业务分类和组合筛选。
  • Object 标签:直接读写对象存储原生标签,适合生命周期、计费或其它云侧规则。

两者用途不同,因此没有被合并成同一套数据。

上传与下载#

小文件使用预签名 PUT URL 直传。

超过默认阈值的大文件进入分片上传流程,前端按配置的分片大小切分文件,并行上传多个分片,最后由后端完成合并和登记。

下载使用短期预签名 GET URL。批量下载则由后端读取多个对象并生成压缩流。

管理与对账#

云存储管理员可以管理:

  • 团队成员与存储级权限。
  • 索引同步和差异问题。
  • Bucket 生命周期规则。
  • Bucket CORS。
  • 阿里云 OSS 防盗链。
  • Object 标签预设。
  • 文件命名规则。

数据模型#

数据库模型围绕四组信息展开。

身份与权限#

  • User:SSO 用户或内置用户。
  • Permission:平台权限或云存储权限。
  • UserPermission:用户与权限的多对多关系。

云存储与文件#

  • CloudStorage:Bucket、协议、加密配置和上传策略。
  • FileObject:文件索引、ObjectKey、大小、ETag、状态和上传人。
  • UploadSession:直传或分片上传会话。
  • ImageMetadataImageRawPair:图片元数据和图片/RAW 配对信息。

标签#

  • TagTagNamespaceFileTag:系统标签体系。
  • ObjectTagPreset:对象存储原生标签的预设模板。

对账与审计#

  • StorageSyncRun:一次分步同步任务。
  • StorageSyncIssue:缺失对象或内容变化问题。
  • AuditLog:记录管理操作和关键文件操作。

为什么同时需要远端浏览和数据库搜索#

这是项目中最容易混淆的边界。

如果所有页面都只读数据库:

  • 看不到外部程序刚刚写入的对象。
  • 数据库记录可能已经失真。
  • 用户会误以为数据库就是 Bucket 本身。

如果所有页面都实时扫描对象存储:

  • 无法高效做复杂搜索和多标签组合。
  • 大 Bucket 的查询成本高、等待时间长。
  • 很难保存上传人、业务标签和操作状态。

OSS Hub 的选择是:

  • 文件浏览以对象存储实时列表为主。
  • 搜索和标签查询以数据库索引为主。
  • 对账模块负责发现两者之间的偏差。

项目的取舍#

不代理普通文件上传#

文件经过后端会增加带宽、内存和磁盘压力,也会让大文件上传更容易受应用服务重启影响。因此普通上传默认使用预签名直传。

不向前端下发永久凭据#

浏览器只拿到短期、限定对象 Key 和请求方法的 URL。即使 URL 泄漏,影响范围也远小于 AK/SK 泄漏。

不强行抹平所有云厂商差异#

通用能力进入 StorageProvider 接口;阿里云图片处理、防盗链等扩展能力则保留协议能力判断。这样既能复用主链路,也不会制造“所有供应商都支持”的假象。

默认支持单实例,也准备数据库演进路径#

SQLite 降低本地部署和个人使用门槛;项目同时维护 PostgreSQL schema、复制、校验、切换和回滚脚本,为更正式的部署预留路径。

演示重点#

如果第一次演示 OSS Hub,推荐按下面顺序:

  1. 登录并切换当前云存储。
  2. 在文件页面浏览目录、切换列表和图标视图。
  3. 上传一个小文件和一个大文件,观察两种上传链路。
  4. 打开图片或文本预览。
  5. 给文件添加系统标签和 Object 标签。
  6. 在搜索页按文件名和标签找到文件。
  7. 在管理页运行索引同步,展示差异问题。
  8. 切换到移动端,展示操作 Sheet 和移动端预览。

后面的文章会分别展开这些实现。

OSS Hub:为什么要做一个统一对象存储管理平台
https://march7th.online/blog/posts/0039-oss-hub为什么要做一个统一对象存储管理平台/
作者
Yiguo
发布于
2026-07-28
许可协议
CC BY-NC-SA 4.0
最后更新于 2026-07-28,距今已过 3 天

部分内容可能已过时

所属合集

OSS Hub 对象存储管理平台

记录 OSS Hub 从项目定位、多云对象存储适配、浏览器直传、索引对账,到 Vue 管理后台、部署和工程化收尾的完整实现。

查看完整合集

目录