aslan-h5/docs/security/atu-prod-hardening-playbook.zh-CN.md
2026-04-21 16:42:29 +08:00

12 KiB
Raw Blame History

atu-prod 分支前端加固迁移执行手册

目的

这份文档用于在后续切换到 atu-prod 分支后,按固定步骤复用当前分支已经落地的前端防扒取加固方案。

使用方式很简单:

  • 当你切到 atu-prod 后,只要说明“按 atu-prod-hardening-playbook.zh-CN.md 执行”
  • 我就按这份文档中的顺序检查、迁移、修复和验证

这份文档不是泛泛的说明,而是面向实际执行的作业手册。

适用前提

  • atu-prod 分支与当前分支在业务功能上大体一致
  • 主要差异集中在样式、布局、局部结构命名
  • 活动页和榜单页的核心交互、接口、资源使用方式基本相同

如果后续发现 atu-prod 在页面结构上差异很大,这份手册仍然能作为基线,但执行时要允许局部调整。

迁移目标

切换到 atu-prod 后,需要尽量恢复当前分支已经完成的这些能力:

  1. 受保护页面仅允许在 App 环境下访问
  2. 运行时基础防调试、防复制、防拖拽和动态水印
  3. Activities / Ranking 图片地址保护与运行时解析
  4. background-image 相关真实图链泄露点收口
  5. 构建产物哈希化和可读性降低
  6. 生产相关模式日志清理与保留日志开关
  7. v-showv-if 的主内容延迟挂载改造
  8. BackgroundLayeruseCanvas 背景合成方案
  9. 明显语义类名收口
  10. 已发现问题页的修复和清理

执行顺序

后续在 atu-prod 分支执行时,按下面顺序做,不要跳步。

第 1 步:先对照基础能力文件

优先检查这些全局能力文件是否已经存在、是否需要同步:

这一步的目标是先把“全局基础设施”对齐,再进页面级迁移。

第 2 步:扫描 Activities / Ranking 页面

重点扫描这两个目录:

执行时重点看四类点:

  1. 是否仍有大量直接 <img :src="getPngUrl(...)" />
  2. 是否仍有 background-image: url(...)
  3. 是否存在 v-show="!isLoading" 控制主内容
  4. 是否存在明显语义类名、明显业务含义 chunk 入口、测试日志

第 3 步:优先迁移高风险页面

后续在 atu-prod 中优先处理这些已经确认过风险较高、且当前分支已加固的页面:

页面级迁移检查清单

后续每处理一个页面,都按这份清单检查。

A. 图片链路

  • 是否统一通过 getPngUrl() / getWebpUrl() 走受保护地址
  • 是否尽量使用 v-smart-img
  • 是否存在直接暴露真实 OSS 地址的模板位点
  • 是否存在必须保留的 CSS 背景图场景

B. 背景层

  • 页面背景是否可改成 BackgroundLayer.vue
  • 如果是多层纯装饰背景,是否开启 :useCanvas="true"
  • 如果只是普通内容图,不强制改成 canvas

说明:

  • useCanvas 不应一刀切设成默认值 true
  • 它只针对敏感背景层启用,避免把普通页面也全部切到更重的渲染路径

C. 主内容挂载时机

  • 页面是否仍使用 v-show="!isLoading" 控制主内容
  • 如果页面存在预加载和监听时序问题,优先改成 v-if="!isLoading"
  • 如果页面依赖 IntersectionObserver,应在 await nextTick() 后再注册
  • 如果预加载可能失败,确保在 finally 中放行主内容,避免整页空白

D. 语义暴露

  • 是否有过于直白的局部类名
  • 是否有业务含义明显的本地变量名或测试痕迹
  • 是否有无用日志、调试文案、历史残留注释

E. 组件生命周期

  • IntersectionObserver 是否在卸载时 disconnect()
  • 定时器是否在卸载时清理
  • 残留监听代码是否已经失效却未移除

已知问题与处理记录

后续迁到 atu-prod 时,优先留意这些已经踩过的坑。

1. v-show 会让主内容 DOM 提前暴露

现象:

  • 页面还在预加载时DOM 已经被挂载
  • 容易被直接从 Elements 面板里抄结构
  • 某些触底监听也会因为节点时序问题失灵

处理方式:

  • 将主内容改为 v-if="!isLoading"
  • 对依赖监听的组件,在 nextTick() 后注册观察器
  • finally 中放行主内容

涉及页面:

  • LoginReward
  • LuckyDollars/Season4
  • SpringFestival
  • Ranking/Couple
  • Ranking/Overall

2. IntersectionObserver 挂载时机不稳

现象:

  • 监听节点存在,但绑定太早
  • 页面结构还没稳定时就执行 observe()
  • 页面切走后观察器残留

处理方式:

  • await nextTick()
  • observer.observe(...)
  • onUnmounteddisconnect()

重点页面:

3. Ranking/Couple/Ranking.vue 曾有残留无效加载监听代码

现象:

  • 组件里保留了已经取消的加载模块逻辑
  • 相关 ref 节点已不存在,但监听代码还在

处理方式:

  • 清理失效的 IntersectionObserver 逻辑
  • 删除无效加载模块相关变量
  • 保留当前真实在用的数据展示逻辑

4. Ranking/Couple/Ranking.vue 曾出现乱码注释

现象:

  • 早期编辑和编码处理后,中文注释出现乱码

处理方式:

  • 清理乱码注释
  • 统一改为中文注释
  • 保持逻辑不变,只修复可读性

5. BackgroundLayer 为什么不是默认 useCanvas=true

结论:

  • 因为它是公共组件
  • 默认全开会把所有背景层都切到 canvas 路径
  • 会增加普通页面的图片加载、重绘和兼容风险

当前策略:

  • 只在高风险的 Activities / Ranking 页面显式传入 :useCanvas="true"

6. toCssBackgroundImage() 的作用

结论:

  • 它不是加密层
  • 它是把 likei-protected: 地址还原成 CSS 可用的 url(...)
  • 主要用于必须保留 background-image 的点位

相关文件:

构建与验证步骤

基础构建

执行:

npm run build

预期:

  • 构建成功
  • 保留已知提示,但不新增本轮改动引起的报错

生产态验证

执行:

npm run dev:prod

或:

npm run build
npm run preview

验证点:

  • 非 App 环境访问受保护页会被拦截
  • 公共页可正常打开
  • Activities / Ranking 页面的图片仍能显示
  • BackgroundLayer 的 canvas 背景仍能正常渲染
  • 触底加载和倒计时逻辑不受影响

日志构建验证

执行:

npm run build:prod
npm run build:prod:logs
npm run build:atu-prod
npm run build:atu-prod:logs

验证点:

  • 默认生产相关包清理 console.logconsole.debugconsole.infodebugger
  • :logs 的命令仍保留调试日志,便于 App 内定位问题
  • Jenkins 使用原有命令不需要改发布流程

建议的迁移方法

后续切到 atu-prod 后,建议按下面方式推进:

  1. 先同步全局基础能力文件
  2. 再扫描 Activities / Ranking
  3. 先迁移高风险页面
  4. 每迁移一页就做局部验证
  5. 最后统一跑 npm run build
  6. 再补文档同步

后续文档同步方法

如果后续主分支继续更新了这些安全文档,想把最新 md 同步到当前分支,不需要再手工复制。

先决条件:

  • 主分支上的文档更新已经提交到 Git
  • 当前已经切换到目标分支,例如 atu_prod

执行命令:

npm run docs:sync:security -- master

如果你想从远端主分支同步,也可以用:

npm run docs:sync:security -- origin/master

这条命令会同步这些文件:

  • docs/security/frontend-hardening.md
  • docs/security/frontend-hardening.zh-CN.md
  • docs/security/frontend-hardening.zh-CN.updates.md
  • docs/security/atu-prod-hardening-playbook.zh-CN.md

对应脚本文件:

注意:

  • 如果源分支里还没有提交这些 md脚本会直接报错
  • 所以推荐流程是“先在主分支提交文档,再切到目标分支执行同步命令”

文档同步要求

后续在 atu-prod 做迁移时,文档也要同步更新,至少包含:

  • 本次迁移到 atu-prod 的实际范围
  • 哪些页面已迁移
  • 哪些页面因结构差异暂未迁移
  • 新遇到的问题和处理方式
  • 最终验证结果

建议优先更新这些文档:

后续对我下指令的推荐说法

后续你切到 atu-prod 分支后,可以直接这样说:

  • atu-prod-hardening-playbook.zh-CN.md 执行一遍
  • 先按手册同步全局加固能力,再扫描 Activities / Ranking
  • 按手册把高风险页面优先迁移,并同步更新文档

看到这类指令后,我默认会:

  • 先核对分支当前状态
  • 再按这份文档逐项执行
  • 遇到结构差异时在不偏离目标的前提下做适配
  • 最后把实际执行结果写回文档