上线前夜,我对着这份清单又划掉了三个"以为不会出事"的侥幸心理
上周帮朋友公司救急,他们一个新系统上线两小时就炸了锅:超管能进普通用户后台,菜单里藏着没权限校验的测试页面,OSS 回调地址还是本地的 127.0.0.1。最讽刺的是,这些问题我在自己项目里几乎全踩过,只是运气好没在同一个晚上集体爆发。
后来我把每次上线前手工过一遍的动作,整理成了一张能打印出来的清单。不复杂,但专治"我以为改了"和"应该没问题"。
一、权限:别只测"能不能进",要测"不该进的进不进得去"
我现在的习惯是拉三张表:角色表、规则表、关联表。然后做两轮验证——正向用每个角色登录,把菜单点一遍;反向直接用接口工具,把没分配的权限 ID 拼进 URL 里硬闯。上次就抓到一个 bug:前端按钮藏了,但路由里漏了 `middleware('auth')`,Postman 一敲直接裸奔。
特别提醒:如果用了动态权限(比如按部门、按项目隔离),一定要造"跨边界"的测试数据。我吃过亏,A 部门用户能看到 B 部门报表,因为 SQL 里 `where dept_id` 被缓存 key 漏掉了。
二、路由:清理"临时通道",比新增路由更重要
开发阶段为了方便,谁没写过几个 `/test/debug`、`/api/tmp-export` 之类的路由?上线前必须全局搜这几个关键词:`test`、`debug`、`tmp`、`demo`、`dev`。我现在的项目里有个 `Route::getRoutes()` 遍历脚本,输出所有已注册路由,人工扫一遍比靠脑子记靠谱。
还有隐藏风险:框架自动注册的资源路由。ThinkPHP 的 `resource()` 会一次性生成七条路由,如果你只覆盖了 `index` 和 `store`,剩下的 `edit`、`destroy` 可能变成无人看守的后门。
三、菜单:前后台菜单要"对账",不能各管各的
很多系统菜单存在两个地方:数据库的权限菜单表(给后端鉴权用)和前端的菜单配置文件(给界面渲染用)。我见过最离谱的情况是,后端删了某个模块的权限,但前端菜单里还挂着,点进去 403;或者前端藏了入口,但用户直接拼 URL 还是能访问。
我的做法是用脚本比对两边:导出数据库菜单的 `name` 字段,和前端路由配置的 `name` 做 diff。不一致的标红,上线前必须清零。如果用了动态菜单(根据权限实时生成),则要额外检查"有权限但菜单没显示"和"没权限但菜单亮着"两种情况。
四、配置:区分"环境配置"和"业务配置",别混着管
`.env` 里放什么、数据库配置表放什么、缓存里放什么,边界必须清楚。我现在的规矩是:环境相关(数据库连接、密钥、调试开关)全进 `.env`,业务相关(网站标题、客服电话、功能开关)进数据库配置表,运行时高频读取的做缓存但必须有失效兜底。
上线前核对清单:`.env.example` 有没有同步最新字段?生产环境的 `.env` 是不是从测试环境直接复制过来的(里面可能藏着 `APP_DEBUG=true`)?配置表里的默认值,在新环境数据库里是否存在?我吃过一次亏,新环境配置表是空的,代码里 `config('site.title')` 返回 null,前端直接白屏。
五、额外加的两道"保险丝"
一是"降级开关":核心功能依赖的第三方服务(短信、支付、OSS),在配置里预留一个 `mock_mode`,万一对方挂了能立刻切本地模拟返回,而不是全站卡住。
二是"上线后 30 分钟观察期":把错误日志级别临时调高,盯一波 `warning` 以上的条目。很多配置问题不会立刻爆 500,而是先以"数据不对""功能时灵时不灵"的形式潜伏。
这份清单我现在每次上线前打印出来,用笔划勾。电子化反而容易敷衍,纸上的红勾黑叉更有仪式感——也更不容易骗自己"好像看过了"。
你们上线前有什么必做的"土办法"?或者因为漏了哪一步,事后拍断大腿的?