11 KiB
五端文件签名验证记录
验证日期:2026-10-29。范围为本地五个项目的实现、定向回归、构建和已登录后台页面检查。未发布服务、修改 Nacos、开启生产拦截、更新真实设备、执行数据库迁移或提交 Git。
已完成
| 验证 | 结果 |
|---|---|
| Java 请求级与业务回归 | 41 项通过,0 失败;覆盖 UPMS 文件校验/读取、版本地址、钱包和硬件导出,同时编译相关公共模块及 canteen |
| 后台自动测试 | 14 项通过,包含文件协议与已有部门导出测试 |
| H5 文件自动测试 | 14 项通过 |
| 小程序文件自动测试 | 14 项通过 |
| 跨语言协议 | Java、三端 TypeScript、Dart 使用相同公开向量;校验 UTF-8 文件名、秒级时间戳、Base64URL 原文和 HMAC 结果 |
| URL 与运行时 | 覆盖中文、空格、加号、百分号编码、历史域名、相对/绝对地址、已有 /api 前缀、重复签名、第三方地址;前端测试执行实际运行时包装器,H5/小程序测试执行富文本预览组件的 JS 方法;Java 使用真实 SpringMvcContract/Feign 客户端与内存传输验证文件名字面 %2F/%2B、重复拦截和参数顺序 |
| 后台生产构建 | pnpm build:prod 通过 |
| H5 构建 | pnpm build:h5 通过 |
| 微信小程序构建 | pnpm build:mp-weixin 通过 |
| Flutter 定向回归 | 56 项通过;含签名、安装包一次重试、人脸同步计划/流水线/失败记录/缓存、主副屏余额回归 |
| Android Release | FVM Flutter 3.27.4 构建通过,使用 .file-access/production.json;APK 约 101.9 MB |
| 新增后台 TypeScript 工具 | 独立严格类型检查通过 |
| 配置生成器 | 在临时目录重复运行,确认幂等、保留已有文件;开发/测试/生产配置和各客户端密钥相互独立 |
| 密钥与原有变更 | 扫描五个项目全部已跟踪及未忽略候选文件,未发现生成密钥泄漏;后台原有补丁可反向校验,Java 原有补丁除追加忽略规则产生的上下文差异外可反向校验 |
| Diff 检查 | 保留原有 CRLF 文件格式;使用 git -c core.whitespace=cr-at-eol diff --check 通过 |
APK 位置(相对本仓库):../pj_supermarket_cloud/build/app/outputs/flutter-apk/app-release.apk。本次构建尚未在真实终端安装验证;发布前须核对包内环境与服务端配置一致。
Java 定向测试及各端构建命令见 接入与发布说明。本机详细日志保存在 /tmp/pj-file-access-work/,属于临时验证资料,不随仓库发布。
静态检查与既有问题
使用任务开始前保存的补丁还原临时代码基线,与当前代码运行同一检查后比较:
| 项目 | 当前结果与基线比较 |
|---|---|
后台 vue-tsc |
6 条既有解析错误,均在 src/views/admin/system/tenant/index.vue:83;与基线完全一致 |
H5 vue-tsc |
4 条既有解析错误,在 src/pages/tabbar/~individualOrder.vue:78-79;与基线完全一致 |
小程序 vue-tsc |
17 条既有 TS6504(JS Vue 来源与 allowJs 配置);规范化临时目录路径后与基线完全一致 |
Flutter analyze --no-pub |
69 条提示/警告;忽略因新增代码产生的行号偏移后,诊断集合与基线完全一致,无新增项 |
因此不能把本次结果表述为“全项目类型检查通过”。H5/小程序构建仍有 TM UI 类型导出和循环依赖等构建提示;构建已成功,未在本次跨端文件改造中整理无关依赖。
已登录后台检查
使用用户提供的 http://localhost:8888/ 已登录会话,检查文件管理页:
- 本系统有效图片的缩略图与放大预览加载成功,资源请求带
appId/kid/ts/sign,fileName位于最后。 - 实测发现并修复前端
/api前缀被重复保留的问题:当前开发图片服务器不带/api,相对旧路径应转换为/admin/sys-file/oss/file。配置含/api的部署仍保留一次前缀。 - 旧头像的一条原始文件链接返回 HTTP 200、内容长度为 0,属于当前运行后端/存储的既有异常。新 Java 读取代码已覆盖不存在和存储异常状态,但尚未发布,不能声称现场问题已修复。
- 当前后端匿名
/admin/sys-file/oss/access-info返回 424 鉴权错误,说明运行环境尚未具备本次匿名校时接口;签名客户端会保留本地时间/最近偏移,不降级匿名读取。 - 点击素材下载后未出现页面错误,但浏览器下载事件未在等待窗口内返回。浏览器工具自动安全检查拒绝打开
chrome://downloads/(仅允许 HTTP/HTTPS),未采用其他方式绕过此限制,下载文件实际落盘未确认。
当前运行后端仍接受裸文件链接。上述浏览器结果证明前端签名与展示链路可用,不代表新后端严格校验已在线生效。
发布前仍需完成
- 核对每个环境的公网基础地址、历史域名、密钥和活动 kid;Java 不会自动加载
.file-access/*.yml,须通过 Nacos 或SPRING_CONFIG_ADDITIONAL_LOCATION加载。先以observe发布 UPMS、integrated 和所有实际调用文件服务的模块。 - 用发布后的后端确认匿名校时可达,执行 GET/HEAD、错误参数、错误/过期签名、旧 Dart 兼容、404/500、私有缓存及服务间读取联调。
- 在真实旧 Flutter 安装包上确认图片请求 UA、图片显示及 Android 原生 APK 下载。新版包确认主副屏、缓存命中、人脸重复同步/离线恢复、取证、打印、手动/自动更新;不能用本地源码或单元测试替代设备验收。
- 微信真机验证登录前 Logo/背景、长时间停留和恢复前台、图片预览、文件下载及打开文档;核对微信文件域名配置。后台与 H5 补充对应实际业务操作验收。
- 至少观察一个完整业务日,确认已知入口无遗漏后再切
enforce;根据设备版本台账确认升级覆盖后再关闭旧 Dart 图片兼容。
当前默认保持 observe 与旧 Dart 图片兼容开启。回滚方法是恢复 observe 并保留诊断日志;业务引用和人脸记录未持久化临时签名,无需数据库回滚。
后台图片闪烁修复补充
2026-10-29 修复后台单张图片失败重试清空全局签名缓存的问题。重试只刷新当前文件,同一文件的并发重试合并;普通校时保留仍有效的签名。新增公共 FileImage,已加载图片在分钟检查、签名续期和恢复前台时保持当前画面;未加载的懒图片继续更新有效地址,放大预览在打开或切换图片时取有效签名。业务引用改变时正常加载新图。
- 后台定向回归 19 项通过,包含真实组件 setup、模板与 Vue 生命周期测试;模拟停留超过 30 分钟、恢复前台、失败重试、预览和懒加载。
- 新组件与文件工具的定向
vue-tsc检查通过;后台生产构建通过。 - 已登录商户页实测:原先已加载的 24 张图片跨分钟检查后地址不变,其余慢图片随后加载完成,共 30 张图片成功、无加载占位;放大预览成功且请求带签名。
浏览器直接打开文件地址限制补充
2026-10-29 新增默认开启的 block-browser-navigation。严格模式下,携带浏览器页面导航 Fetch Metadata 的文件请求,即使签名有效也返回 403;页面图片、音视频、fetch/XHR 下载和无浏览器 Metadata 的原生/服务请求继续按原签名规则处理。成功响应 Vary 区分导航与子资源请求;拒绝响应 no-store。观察模式仅记录 browser_navigation。
- Java 文件访问/读取请求级测试共 12 项通过,覆盖签名正确的导航、GET/HEAD 在读取存储前拒绝、图片与下载放行、原生包下载、Dart UA 不绕过导航限制、开关和观察模式。
- 后台 20 项、H5 16 项、小程序 16 项定向测试通过。覆盖文件链接的页面内下载、H5 富文本与普通链接拦截、图片预览、本地文档打开及第三方链接保持原行为。
- 后台生产、H5、微信小程序构建通过;后台文件组件/工具定向类型检查通过。
- 配置生成器在临时目录验证:新配置含
block-browser-navigation: true,默认仍为observe,没有修改实际运行环境配置。
这项补充尚未部署到文件服务器,不能把本地请求级测试表述为该公网地址已返回 403。上线时代理须保留 Sec-Fetch-Mode/Dest 和响应 Vary;用新签名或无旧缓存的窗口验证。后端无法收回浏览器已经取得的文件内容。旧浏览器可能不提供 Fetch Metadata,脚本也能模拟请求,因此这项规则不等于逐用户授权或防止已显示图片被保存。
最终调整:统一一套密钥与严格模式联调
用户明确要求所有环境使用同一套密钥,取代本文前面记录的开发/测试/生产独立密钥方案。沿用已配置的原生产密钥组,未生成新密钥;各 appId 仍使用各自固定密钥,service/package 密钥仍只存在服务端。三个前端统一使用 .env.local,Java 使用 .file-access/config.yml,Flutter 使用 .file-access/config.json。旧模式文件的签名字段已清理并备份,旧命令 --environment 不再切换密钥。
此前严格模式白图的真实原因是:浏览器按开发密钥签名,后端配置的是原生产密钥,实际响应为 invalid_signature。本次已通过本地 Nacos REST API 修正 application-dev.yml,保留 enforce、浏览器导航拦截和旧 Dart 兼容,公网基础地址对齐测试网关。Nacos 完整原配置保存在本机私有临时备份,发布时使用 MD5 比较避免覆盖并发编辑,生产服务配置未修改。
- 使用真实页面中的同一个签名 URL 联调:页面图片请求 200、应用下载请求 200、浏览器导航请求 403,原因为
browser_navigation。 - 实际后台重新加载后,首轮观察为 30 张图片中的 24 张加载成功,其余 6 张仍在慢请求中;随后浏览器自动化连接中断,未把该轮全部图片的最终状态作为已验证结果。签名已与统一密钥注册表一致。
- 真实 Vite
loadEnv验证三个项目共 18 个模式组合,全部使用统一密钥;生成器迁移、重复执行、原密钥保留与错误配置拒绝共 3 项测试通过。 - 后台生产、H5、微信小程序构建通过;Flutter 使用统一配置执行签名和安装包定向测试,8 项通过。
后续构建与配置准备以 README 中的统一路径为准。本文前面提到的分环境配置路径属于历史验证记录,不再作为当前操作指引。