12 KiB
12 KiB
atu-prod 分支前端加固迁移执行手册
目的
这份文档用于在后续切换到 atu-prod 分支后,按固定步骤复用当前分支已经落地的前端防扒取加固方案。
使用方式很简单:
- 当你切到
atu-prod后,只要说明“按atu-prod-hardening-playbook.zh-CN.md执行” - 我就按这份文档中的顺序检查、迁移、修复和验证
这份文档不是泛泛的说明,而是面向实际执行的作业手册。
适用前提
atu-prod分支与当前分支在业务功能上大体一致- 主要差异集中在样式、布局、局部结构命名
- 活动页和榜单页的核心交互、接口、资源使用方式基本相同
如果后续发现 atu-prod 在页面结构上差异很大,这份手册仍然能作为基线,但执行时要允许局部调整。
迁移目标
切换到 atu-prod 后,需要尽量恢复当前分支已经完成的这些能力:
- 受保护页面仅允许在 App 环境下访问
- 运行时基础防调试、防复制、防拖拽和动态水印
Activities / Ranking图片地址保护与运行时解析background-image相关真实图链泄露点收口- 构建产物哈希化和可读性降低
- 生产相关模式日志清理与保留日志开关
v-show到v-if的主内容延迟挂载改造BackgroundLayer的useCanvas背景合成方案- 明显语义类名收口
- 已发现问题页的修复和清理
执行顺序
后续在 atu-prod 分支执行时,按下面顺序做,不要跳步。
第 1 步:先对照基础能力文件
优先检查这些全局能力文件是否已经存在、是否需要同步:
- src/utils/routeGuard.js
- src/utils/http.js
- src/config/security.js
- src/utils/runtimeSecurity.js
- src/main.js
- src/App.vue
- src/config/imagePaths.js
- src/utils/protectedAssets.js
- src/utils/protectedAssetRuntime.js
- src/directives/smartImage.js
- src/utils/image/imageCacheManager.js
- src/components/BackgroundLayer.vue
- vite.config.js
- package.json
- scripts/build-with-version.js
这一步的目标是先把“全局基础设施”对齐,再进页面级迁移。
第 2 步:扫描 Activities / Ranking 页面
重点扫描这两个目录:
执行时重点看四类点:
- 是否仍有大量直接
<img :src="getPngUrl(...)" /> - 是否仍有
background-image: url(...) - 是否存在
v-show="!isLoading"控制主内容 - 是否存在明显语义类名、明显业务含义 chunk 入口、测试日志
第 3 步:优先迁移高风险页面
后续在 atu-prod 中优先处理这些已经确认过风险较高、且当前分支已加固的页面:
- src/views/Activities/LesserBairam/index.vue
- src/views/Activities/LoginReward/index.vue
- src/views/Activities/LuckyDollars/Season3/index.vue
- src/views/Activities/LuckyDollars/Season4/index.vue
- src/views/Activities/SpringFestival/index.vue
- src/views/Activities/SpringFestival/Ranking.vue
- src/views/Activities/SpringFestival/Task.vue
- src/views/Ranking/Couple/index.vue
- src/views/Ranking/Couple/Ranking.vue
- src/views/Ranking/GamesKing/index.vue
- src/views/Ranking/KingAndQueen/TopList.vue
- src/views/Ranking/Overall/Ranking.vue
- src/views/Ranking/WeeklyStar/WeeklyStar.vue
页面级迁移检查清单
后续每处理一个页面,都按这份清单检查。
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中放行主内容
涉及页面:
LoginRewardLuckyDollars/Season4SpringFestivalRanking/CoupleRanking/Overall
2. IntersectionObserver 挂载时机不稳
现象:
- 监听节点存在,但绑定太早
- 页面结构还没稳定时就执行
observe() - 页面切走后观察器残留
处理方式:
await nextTick()- 再
observer.observe(...) onUnmounted时disconnect()
重点页面:
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.log、console.debug、console.info、debugger - 带
:logs的命令仍保留调试日志,便于 App 内定位问题 - Jenkins 使用原有命令不需要改发布流程
建议的迁移方法
后续切到 atu-prod 后,建议按下面方式推进:
- 先同步全局基础能力文件
- 再扫描
Activities / Ranking - 先迁移高风险页面
- 每迁移一页就做局部验证
- 最后统一跑
npm run build - 再补文档同步
后续文档同步方法
如果后续主分支继续更新了这些安全文档,想把最新 md 同步到当前分支,不需要再手工复制。
先决条件:
- 主分支上的文档更新已经提交到 Git
- 当前已经切换到目标分支,例如
atu_prod
执行命令:
npm run docs:sync:security -- master
如果你想从远端主分支同步,也可以用:
npm run docs:sync:security -- origin/master
这条命令会同步这些文件:
docs/security/frontend-hardening.mddocs/security/frontend-hardening.zh-CN.mddocs/security/frontend-hardening.zh-CN.updates.mddocs/security/atu-prod-hardening-playbook.zh-CN.md
对应脚本文件:
注意:
- 如果源分支里还没有提交这些 md,脚本会直接报错
- 所以推荐流程是“先在主分支提交文档,再切到目标分支执行同步命令”
文档同步要求
后续在 atu-prod 做迁移时,文档也要同步更新,至少包含:
- 本次迁移到
atu-prod的实际范围 - 哪些页面已迁移
- 哪些页面因结构差异暂未迁移
- 新遇到的问题和处理方式
- 最终验证结果
建议优先更新这些文档:
- docs/security/frontend-hardening.zh-CN.md
- docs/security/frontend-hardening.zh-CN.updates.md
- docs/security/atu-prod-hardening-playbook.zh-CN.md
后续对我下指令的推荐说法
后续你切到 atu-prod 分支后,可以直接这样说:
- 按
atu-prod-hardening-playbook.zh-CN.md执行一遍 - 先按手册同步全局加固能力,再扫描
Activities / Ranking - 按手册把高风险页面优先迁移,并同步更新文档
看到这类指令后,我默认会:
- 先核对分支当前状态
- 再按这份文档逐项执行
- 遇到结构差异时在不偏离目标的前提下做适配
- 最后把实际执行结果写回文档