鸿蒙云相册实战笔记:OBS Header 签名、逐文件备份与 AI Shell 追问 403 排查
今天的路线很具体:先在鸿蒙开发实践中心读完案例《用OBS打造个人云相册app》,再到 AI DevSpace 的 AI Shell 里追问同一个问题——OBS Header 签名到底怎么算,备份返回 403 又从哪里查。本文就是这次阅读加追问的实操笔记,只写今天实际看到和问到的内容,不虚构没有做过的上线结果。
一、案例在做什么
案例目标是做一个个人云相册 App:从本地图库选择照片和视频,经 OBS Header 签名逐文件备份到自己的私有桶,再在云端列表和网格里查看缩略图、对象详情与预览。技术栈是 ArkTS 与 ArkUI,目标 API 26,预计学习时间 120 分钟。
应用分成四个页面:本地图库、备份记录、云端和设置。ArkUI 页面连接媒体扫描、备份服务、OBS 客户端和预览缓存,配置与备份记录保存在应用沙箱 preferences 里。首次进入图库要授权相册读取权限,在设置里填入 AK、SK、区域 Endpoint 和桶名并保存,再选择测试文件或全部待备份项目开始备份。
前置条件很实在:先要有 OBS 桶和四项配置。桶选标准存储、私有访问;资源包买了也不会自动建桶,地域与单、多 AZ 必须匹配,否则抵扣不上、按需计费。AK、SK 从控制台“我的凭证—访问密钥”获取,只在 App 设置里填写,不要放进代码、日志或截图。案例建议用只开“编程访问”的专用 IAM 用户,只给目标桶的 ListBucket、PutObject、GetObject 权限。
二、核心链路只有三步
第一步是选文件。案例用 photoAccessHelper 读取本地相册,支持筛选、多选或备份全部待备份文件,备份时显示进度并支持取消。第二步是签名上传:对每个文件构造 OBS Header 签名请求,用 PUT 逐文件上传。第三步是云端查看:列举桶内对象,在列表与网格之间切换,通过认证 GET 预览图片和视频。
这里有两个容易被忽略的边界。单文件上传和预览上限是 64 MiB,云预览磁盘缓存上限 128 MiB,缩略图最多 64 张。超过 64 MiB 的家庭视频不在基础链路里,要走后面讲的分段上传拓展任务。
三、OBS Header 签名拆开讲
这是今天花时间最长的部分,也是最容易写错的地方。OBS Header 签名属于 S3 V2 兼容方案,核心是三步:先拼 StringToSign,再用 SK 做 HMAC-SHA1 并 Base64 编码得到 Signature,最后放进请求头 Authorization: OBS AK:Signature,其中 OBS 是固定标识符,不是 AWS。签的是请求本身(方法、路径、请求头、资源),不是 body;SK 永远不上线,只参与本地 HMAC 计算。
StringToSign 由六段按固定顺序、用换行符拼接:HTTP 方法,如 PUT、GET,必须大写;Content-MD5,无 body 时留空行;Content-Type,如 image/jpeg,无此头留空行;Date,请求时间,RFC1123 格式,或用 x-obs-date 头代替;CanonicalizedObsHeaders,所有以 x-obs- 开头的自定义头,按字典序升序排列,每行一个,格式为小写头名加去空格的值;CanonicalizedResource,规范化资源路径,即“/桶名/对象 key”,再拼接查询子资源。顺序不能乱,少一行、多一行、大小写不一致,服务端重算的签名就会和客户端对不上。
四、403 SignatureDoesNotMatch,先查这五项
我在 AI Shell 里问的正是这个问题。按“最常见到较少见”排序,排查清单如下。
第一,AK、SK 是否正确且成对。复制时漏字符、混入空格、用错账号的密钥对都会 403;AK 和 SK 必须是同一对,还要确认这对密钥对目标桶有写权限。
第二,本机时间偏差。OBS 要求请求时间与服务器相差不超过 15 分钟,否则直接拒绝,常被误判成签名错。先看本机时间是否准、NTP 是否同步。
第三,x-obs 头拼接是否规范。头名必须全小写,值前后空格要去掉,多个头必须按头名字典序排列。漏签一个 x-obs 头,比如设了 x-obs-acl 却没把它算进签名串,是最经典的 403 原因。
第四,Content-MD5 与 Content-Type 是否与实际 body 一致。上传图片时头里声明的 MD5 与实际文件算出来对不上,或 Content-Type 大小写、值与签名时不一致,签名就会错。
第五,桶名与对象 key 的大小写、URL 编码,以及 Endpoint 与 Region 是否匹配。桶名必须小写,对象 key 区分大小写,含中文或空格的文件名编码出错是高频坑;用了 A 地域的桶却签成 B 地域的 Endpoint,会引发重定向后签名失效的连锁问题。另外要确认客户端用的是 Header 签名还是 QueryString 签名,混用会导致服务端按另一种规则校验。
一句话总结:签名等于 Base64(HMAC-SHA1(SK, StringToSign)),403 时按 AK、SK 配对、本机时间、x-obs 头排序与大小写、MD5 与类型一致性、桶名小写与 key 编码的顺序查,这五项覆盖了绝大多数 SignatureDoesNotMatch。
五、AI Shell 追问实录:它先坦白了一件事
我在 AI DevSpace 体验版打开 AI Shell,问的是:“请解释今天浏览的鸿蒙个人云相册案例中,OBS Header 签名是怎么构造的?HMAC-SHA1 签名串包含哪些要素?如果备份时返回 403 签名不匹配,应先核对哪些配置?”
AI Shell 的回答先坦白:它检索了记忆库,没有找到今天浏览的案例的具体记录,因为案例是在浏览器里看的,没有进入它的会话上下文,所以下面基于 OBS 通用 Header 签名机制(S3 V2 兼容、HMAC-SHA1)回答。这正是我想在文章里写清楚的一点:AI 的回答结构很完整,六段签名串和五项排查清单都对得上案例里的说法,但它没有读过案例原文,回答是通用机制的复述,不是针对案例代码的核对。
这给我的启示是:用 AI Shell 追问,要把它当作“先给出一份可核对的检查清单”,而不是定论。正确用法是拿着它的清单,再回案例原文逐项对照——案例里写了 HMAC-SHA1、Authorization 请求头、403 先核对四项配置与设备时间;AI 的清单更细,补上了 x-obs 头排序、MD5 一致性、key 编码这些点。下一步真正动手时,应该把案例里的 ObsClient.ets、BackupService.ets 里的签名拼接代码贴给 AI,让它逐行定位,而不是只问通用概念。
六、备份去重与四个拓展任务
除了签名,案例里还有两处值得记的设计。第一是去重:备份时按目标和内容识别重复文件,依据是同一目标下的备份记录和 MD5;上传使用 x-obs-forbid-overwrite 做同名对象保护,但版本控制桶的行为要按 OBS 文档和桶配置核对,不能依赖它阻止产生新版本。第二是云相册时间轴:按 OBS 对象的 lastModified 分组,这是备份或上传时间,不是 EXIF 拍摄时间,写时间轴时必须标明时区,不能写成拍摄时间。
案例还给了四个可独立选做的拓展任务:分段上传大文件,验收是超过 64 MiB 的视频可初始化、分段并合并为可读取对象,失败或取消有明确处理结果,完整性校验不把分段 ETag 当整文件 MD5;云相册时间轴,按备份时间分组筛选,时区明确、空态正确;文档选择备份,通过系统选择器备份 PDF、TXT,不支持类型要有提示;云端下载恢复,经用户确认把云端媒体保存到系统相册,重名不覆盖,取消无半成品,权限拒绝有提示,私有缓存不能当作永久恢复结果。
七、安全与清理:别在小事上翻车
案例在“安全与清理”一节写得很直接,值得全文照做:测试用最小权限凭据和非敏感媒体;密码态只隐藏输入,不加密沙箱中的 AK、SK,生产应用应采用适当的临时授权方案;不要把凭据放入代码、日志、截图或公开问题中。做完测试要保存需要的工程及数据,停止不再使用的云工作区和设备,核对后删除测试对象及不再需要的桶,撤销或轮换测试密钥。桶启用版本管理时,删除当前对象不一定删除历史版本,要按控制台实际版本清理并确认费用。
八、今天的小结
今天只做了三件事:读完一个案例、给它的代码仓点了一个 Star、在 AI Shell 里追问了一次签名与 403 排查。收获可以收成一张检查表:桶与四项配置先备齐;签名按六段顺序拼,x-obs 头小写排序;403 按 AK、SK、时间、x-obs 头、MD5 与类型、桶名与 key 编码的顺序查;去重靠记录加 MD5;时间轴用备份时间不用拍摄时间;测试凭据用完就轮换清理。
下一步可做的验证也很明确:按案例步骤建一个测试桶,用一张非敏感测试照片走通一次备份,刷新云端列表确认对象存在,再故意改错一个 x-obs 头或设备时间,看 403 是否如清单所说出现;然后把分段上传和时间轴两个拓展任务逐个做掉。那时再写一篇,才有真正的运行结果可以对照。
- 点赞
- 收藏
- 关注作者
评论(0)