Agent 使用55 分钟

管理员能看、运营看不到按钮:让 Codex 先画出权限判断链路再动手

运营发来一条消息:“同一个订单详情页,管理员账号能看到‘导出’按钮,我登录后按钮直接消失了,是不是系统出 bug 了?”你打开页面确认:两个账号都能进这个页面,请求也都成功,只是一个有按钮、一个没有。

Codex 实战调试与定位AI 工作流可复制模板

适合人群

维护后台系统权限的工程师

先解决什么

同一个页面管理员能看,运营账号看不到某个按钮

学完结果

权限判断链路图和缺口判断

你会学到什么

让 Codex 找角色来源、权限判断、菜单过滤和接口鉴权。

准备材料:两个账号的角色信息、页面截图、权限配置、相关代码。

交付物:权限判断链路图和缺口判断

边界:专门处理角色与权限的定位。

教程定位

这篇教程解决什么问题

运营发来一条消息:“同一个订单详情页,管理员账号能看到‘导出’按钮,我登录后按钮直接消失了,是不是系统出 bug 了?”你打开页面确认:两个账号都能进这个页面,请求也都成功,只是一个有按钮、一个没有。

这类问题最麻烦的地方在于:按钮不显示不等于接口报错,页面能打开也不等于权限正确。它可能发生在角色来源、前端菜单过滤、按钮级权限、路由守卫、接口鉴权、数据范围过滤中的任何一环,甚至好几环同时有问题。

这篇教程教你一条可复现的排查路径:先把两个账号在页面、接口、权限数据三个层面上的差异记录清楚,再让 Codex 沿着“登录角色来源 → 前端权限数据 → 菜单与按钮控制 → 路由守卫 → 接口鉴权 → 数据过滤”画出完整链路,最后产出一张权限判断链路表和一句明确的缺口判断。你拿到的是“问题在哪一层、证据是什么、应该由谁确认”,而不是让 AI 猜一个原因后直接改权限代码。

读完这篇,你能把“运营看不到按钮”从一句模糊的反馈,变成一份可交接、可复核的权限定位记录。

使用场景

什么情况下最适合用这一套

你是维护后台系统或内部管理平台的工程师,今天接到一个权限差异的反馈。典型场景是这样的:

这类问题的真实原因通常落在几个固定位置:

它们的共同点:权限判断分散在多个文件、多个层面,任何一个环节口径不一致,都会造成“管理员能看、运营看不到”。所以排查的重点不是急着改一个 `if`,而是先把整条链路画出来。

  1. 同一个页面 URL,管理员账号登录后能看到“导出”“编辑”“审核”等按钮或操作入口。
  2. 运营账号登录后,同一按钮不显示;或者按钮显示了,点击后接口返回 403。
  3. 两个账号都能正常登录、都能打开页面,甚至页面里的大部分内容都一样。
  4. 权限配置刚改过,或者刚上线了新版菜单/按钮权限逻辑,问题在某个版本之后出现。
  • 运营账号的角色、部门或权限点配置缺失,或者用户-角色关联数据是旧的;
  • 前端根据菜单配置或权限指令(如 `v-permission`)过滤按钮,运营账号拿到的权限集合里没有对应权限点;
  • 路由守卫或页面级权限把整个入口拦掉了,页面本身是靠默认路由或旧缓存打开的;
  • 后端接口中间件、策略或权限校验对运营账号返回 403/404,前端把按钮隐藏或把错误吞掉了;
  • 管理员账号走了“超管直通”逻辑,普通角色的判断链路和超管完全不同,导致问题只对普通角色暴露;
  • 会话或令牌里的角色/权限快照过期,数据库权限已经改了,但 JWT claims 或缓存里还是旧值。

材料准备

开始前先把材料和边界备齐

开始排查前,先把下面这些材料收齐。材料越完整,Codex 越不容易靠猜:

如果代码量很大,先不要整库丢给 AI。抽一小段能代表判断逻辑的样例即可,例如:

如果涉及真实用户、手机号、公司内部数据,先用测试账号或脱敏数据复现。定位权限问题不需要真实姓名和敏感信息。

  • **两个账号的信息**:管理员账号和运营账号各自的用户名(可脱敏)、角色、所属部门或门店、最近一次登录时间。注意区分“账号本身没有角色”和“角色存在但没有权限点”。
  • **页面截图或复现步骤**:管理员视角和运营视角各一张截图,以及当时访问的完整 URL、查询参数。截图要能看出“按钮有/没有”,最好带上浏览器网络面板。
  • **页面请求与响应**:两个账号打开同一页面时,各自发出了哪些请求;哪些接口返回 200、哪些返回 403/404;响应体里是否包含权限字段(如 `permissions`、`canExport`、`actionList`)。这一步经常直接暴露差异。
  • **权限配置**:角色表、权限点表、用户-角色关联、菜单配置或权限点定义文件。如果权限是从配置中心或数据库加载的,带上对应的导出样例。
  • **相关代码位置**:菜单配置、按钮权限指令或组件、路由守卫、API 路由、鉴权中间件/策略、数据范围过滤逻辑。不需要整仓库,但要让 Codex 能读到这几处。
  • **最近变更**:最近一次上线记录、权限配置变更、角色分配操作,以及“之前正常”的时间点。
  • **测试环境**:能在测试环境用两个账号复现,或者至少能拿到生产环境的只读日志。不要在真实生产账号上直接改权限来试。
  • 菜单配置里“导出”按钮对应的权限点名称;
  • 运营账号当前拥有的权限点列表;
  • 管理员账号同一接口的请求头和响应体(脱敏);
  • 鉴权中间件里判断权限的那几行代码。

实操流程

按这套步骤把工作跑起来

【第一步:把“看不到按钮”钉成四层可对照的描述】

不要带着“运营看不到按钮”这种描述去查代码。先回答四个层面的问题:

把答案写成一两句话,例如:“测试环境 URL `/orders/detail?id=1001`,管理员账号返回 `permissions: [order.export, order.edit]`,运营账号返回 `permissions: [order.view]`;前端按钮按 `order.export` 控制,运营账号因此不显示;直接调用导出接口,运营账号返回 403。”这就是之后给 Codex 的第一段上下文。

【第二步:让 Codex 画出从登录到按钮显示的完整链路】

打开代码仓库,让 Codex 先画链路,而不是找 bug。权限判断通常经过这几层:

让 Codex 输出一张“环节表”:每个环节对应哪个文件、哪个函数、读取什么权限值、如何判断。这张表会暴露一个常见事实:按钮显示、路由守卫、接口鉴权经常使用不同的权限值来源,只是看起来“都在校验权限”。

【第三步:逐层核对两个账号的差异】

拿到链路表之后,对每一层问同一个问题:**这一层用什么权限值做判断?这个值从哪里来?两个账号在这个值上差在哪?**

对照下面六类检查点:

让 Codex 对每个环节给出“管理员值”和“运营值”两列,并标明差异可能在哪一层。不要让它一次只报一个原因,要它把全部可疑点列出来,再按证据强弱排序。

【第四步:用最小对照实验验证】

AI 的结论必须能用实验验证。设计一组最小对照实验,一次只改变一个变量:

这一步通常几分钟就能完成,但价值很大:它把“可能是权限数据问题”和“可能是代码问题”分开,避免改错方向。

【第五步:产出权限判断链路表和缺口判断】

把结论整理成一张权限判断链路表,字段至少包括:

最后写一句明确的缺口判断,例如:“问题在权限数据层:运营角色缺少 `order.export` 权限点,前端按钮和后端接口都按同一权限点判断,补上该权限点后两个层面会同时恢复;是否允许运营导出,需要业务方确认。”

在修改任何东西之前,先让权限负责人确认“运营到底应不应该看到这个按钮”。权限问题经常不是技术 bug,而是业务规则本身没有配对。

  1. **页面层**:同一 URL、同一环境,管理员账号和运营账号看到的页面有什么区别?是按钮不存在、按钮置灰,还是点击后报错?
  2. **接口层**:两个账号打开页面时,各自请求了哪些接口?哪些接口返回 200、哪些返回 403/404?响应体里的权限字段是什么?
  3. **权限数据层**:两个账号当前的角色、权限点、部门/门店范围分别是什么?列出集合差。
  4. **变更层**:这个问题是某次上线后出现的,还是一直存在?权限配置和代码谁先改过?
  5. **角色与权限点集合**:管理员和运营的角色分别映射到哪些权限点?运营是否缺少按钮对应的权限点?权限点是直接配给角色,还是按部门/门店继承?
  6. **权限值来源一致性**:前端按钮用的是接口返回的 `permissions`,还是本地静态配置?如果接口返回了 `order.export`,前端有没有正确读取?
  7. **超管直通逻辑**:代码里有没有 `if (user.isAdmin)` 或“超级管理员跳过校验”的分支?如果有,用管理员账号对照时会掩盖普通角色的真实链路。
  8. **接口与前端口径**:前端隐藏按钮的依据和后端 403 的判断依据是不是同一个权限点?常见坑是前端叫 `order.export`,后端策略里写的是 `order:export` 或 `export_order`,永远对不上。
  9. **缓存与会话**:权限配置改了,但用户的 JWT、Redis 会话或浏览器缓存还是旧快照。测试时让运营重新登录,排除旧会话干扰。
  10. **数据范围**:按钮是否依赖数据状态(如“只有本部门订单可导出”),运营账号的部门匹配不到数据,按钮就按业务规则隐藏。
  • **身份与角色来源**:登录后角色从哪来?是数据库用户-角色表、SSO/企业微信/飞书组映射,还是 JWT claims?角色变更后会不会同步到会话?
  • **前端权限数据**:页面初始化时如何拿到当前用户的权限集合?是登录接口返回、单独权限接口,还是从 localStorage/缓存读取?
  • **菜单与按钮控制**:按钮的显示由什么控制?是菜单配置、权限指令(如 `v-permission`)、组件 props,还是接口响应里的字段?
  • **路由守卫**:进入页面前有没有路由级权限检查?被拦住的页面会不会显示成空白或默认页?
  • **接口鉴权**:后端在路由、中间件、策略或 service 里如何校验权限点?管理员是否走了 `isAdmin` 或超管直通?
  • **数据范围过滤**:即使有权限点,接口返回的数据会不会按部门、门店或团队过滤,导致按钮相关的数据为空?
  • 用运营账号直接调用导出接口(不带页面),看接口本身是否 403。这能区分“前端不显示”和“后端不允许”。
  • 查看两个账号打开页面时的完整请求列表,确认运营账号是否少了某个权限接口的请求,或某个请求返回了 403。
  • 在测试环境给运营账号临时加上按钮对应的权限点(或关联一个已具备该权限的测试角色),看按钮是否出现。出现则说明链路本身正常,缺的是权限数据;不出现则说明前端判断还有别的问题。
  • 对比两个账号的请求头或 JWT claims,确认角色/权限快照是否一致、是否过期。
  • 如果刚发过版,用代码回退或 diff 对照,确认按钮权限判断是否在本次改动中发生变化。
  • 环节(角色来源 / 前端权限数据 / 菜单与按钮 / 路由守卫 / 接口鉴权 / 数据范围);
  • 代码位置(文件与函数);
  • 判断逻辑(读取什么、判断什么);
  • 管理员账号的值;
  • 运营账号的值;
  • 差异与证据(接口响应、权限配置、日志、截图);
  • 建议动作(补权限数据 / 改前端判断 / 改后端策略 / 刷新会话);
  • 归属人(权限管理员 / 前端 / 后端)。

输入示例

可以直接参考的输入材料

下面是一份比较完整的输入样例。你可以直接参考它的组织形式,把真实数据填进去。

注意:样例里的权限点命名和接口是示意。真实排查时,Codex 会逐层核对两个账号拿到的权限值,并指出前后端权限点名称是否一致。

输入样例示例 1可复制后按自己的场景替换。
问题描述:
测试环境后台 /orders/detail?id=1001,管理员账号能看到“导出”按钮,
运营账号看不到。两个账号都能打开页面,页面其他内容一致。

账号信息:
- 管理员:admin01,角色:super_admin,部门:技术部
- 运营:ops02,角色:ops_agent,部门:华东运营部

页面请求(运营账号,网络面板摘要):
- GET /api/orders/detail?id=1001 → 200,响应含 order 数据
- GET /api/me/permissions → 200,返回 ["order.view"]
- 页面无 /api/orders/export 相关请求(因为按钮未渲染)

页面请求(管理员账号,网络面板摘要):
- GET /api/orders/detail?id=1001 → 200
- GET /api/me/permissions → 200,返回 ["order.view", "order.export", "order.edit"]

直接调用(运营账号):
- POST /api/orders/export {id: 1001} → 403 {"code": "FORBIDDEN"}

权限配置(角色权限表 role_permissions):
- super_admin:order.view, order.export, order.edit, user.manage
- ops_agent:order.view

代码位置:
- 菜单配置:web/src/config/menu.ts(导出按钮 permission: "order.export")
- 按钮权限指令:web/src/directives/permission.ts
- 权限接口:api/src/routes/me.ts → getPermissions()
- 后端鉴权中间件:api/src/middleware/requirePermission.ts
- 角色权限读取:api/src/services/rbac.ts

最近变更:
- 3 天前上线“菜单权限点重构”,把 order_export 改名为 order.export;
- 角色权限表 ops_agent 行未随迁移更新。

提示词

可复制使用的提示词

把下面的提示词连同上面的输入样例一起发给 Codex。它要求 AI 输出链路和定位表,而不是直接改代码。

如果仓库里权限相关文件分散,可以先只让 Codex 读角色来源、菜单配置、权限指令、鉴权中间件这几处;如果需要搜索权限点定义,允许它搜索后再回答。

可复制提示词示例 1可复制后按自己的场景替换。
我在排查一个权限问题,请按以下方式帮我,先不要修改任何代码:

1. 读一遍我提供的代码位置,画出“登录角色来源 → 前端权限数据 → 菜单与按钮控制 → 路由守卫 → 接口鉴权 → 数据范围过滤”的完整链路。
2. 对每个环节给出:文件位置、读取的权限值、判断逻辑、管理员账号的值、运营账号的值。
3. 对照角色与权限点集合、权限值来源一致性、超管直通、前后端口径、缓存与会话、数据范围六类检查点,列出所有可疑差异。
4. 结合我提供的页面请求、权限接口响应和直接调用结果,判断差异最可能出现在哪一层,并给出证据。
5. 输出一张“权限判断链路表”,包含:环节、代码位置、判断逻辑、管理员值、运营值、差异、证据、建议动作、归属人。
6. 最后用一句话写出缺口判断:问题在哪一层、依据是什么、需要谁确认业务规则。

如果信息不足,直接列出你还缺哪些材料,不要猜测结论。

输出样例

AI 应该输出到什么程度

用上面的提示词,Codex 可能输出类似下面的链路和定位表(这是说明性样例,不是真实项目的结论):

这个样例展示的是“链路表 + 缺口判断”长什么样。真实输出里,每个结论都应该指向具体的代码行、权限点名称和接口响应,方便你复核。

AI 输出样例示例 1可复制后按自己的场景替换。
权限判断链路:
登录 → SSO/用户表取角色
  → api/src/services/rbac.ts 读取 role_permissions
  → GET /api/me/permissions 返回当前用户权限集合
  → 前端 web/src/config/menu.ts 按 permission: "order.export" 控制“导出”按钮
  → 路由守卫 web/src/router/guard.ts 只校验登录态,不校验按钮权限
  → POST /api/orders/export 由 requirePermission("order.export") 拦截
  → service 层按部门范围过滤导出数据

权限判断链路表:
| 环节 | 代码位置 | 判断逻辑 | 管理员值 | 运营值 | 差异 | 证据 | 建议动作 | 归属人 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 角色来源 | rbac.ts | 从 role_permissions 取权限点 | order.view, order.export, order.edit | order.view | ops_agent 缺 order.export | 权限接口响应 | 确认是否应给运营角色补权限点 | 权限管理员 |
| 前端按钮 | menu.ts / permission.ts | 校验 order.export | 显示 | 不显示 | 权限点缺失导致 | 运营截图 | 补权限点后复验;若业务不允许导出则不补 | 前端/权限管理员 |
| 接口鉴权 | requirePermission.ts | 校验 order.export | 200 | 403 | 同一权限点,行为一致 | 直接调用响应 | 无需改代码 | 后端 |
| 数据范围 | exportService.ts | 按部门过滤 | 全部 | - | 未触发 | 无 | 补权限后按运营部门核对 | 后端 |

缺口判断:
问题在权限数据层:运营角色 ops_agent 的 role_permissions 中缺少 order.export,
前端按钮和后端接口都按同一权限点判断,行为一致。是否允许运营导出属于业务规则,
需要权限负责人确认后,在权限配置中补齐或明确保持不开放。

人工验收

人要怎么检查和改到可用

AI 能帮你把链路和可疑点列全,但“运营到底应不应该有权限”必须由人确认:

不要因为 AI 输出看起来很完整就跳过人工复核。链路表只是排查记录,不是修改授权;涉及权限授予的决定,必须由权限负责人签字确认。

  1. **核对证据**:链路表里每一行差异,都要能在真实环境复现。用两个账号各开一次页面,对照网络面板的请求和响应体;直接调一次接口,确认 403 是否稳定出现。
  2. **确认业务规则**:问权限负责人或业务方:运营角色是否应该导出订单?按钮是所有人都该看到,还是按部门、按数据状态显示?这不是技术问题,AI 无权替你决定。
  3. **前端可见不能代替后端鉴权**:即使按钮显示了,也要确认接口层是否允许;反过来,按钮隐藏也不能当作安全措施。最稳的形态是前端控制体验,后端控制权限。
  4. **先改配置、少改代码**:如果缺的是权限点,先在权限配置或角色分配里补齐,而不是在代码里加“运营也显示”的例外分支。改代码前把当前行为记录下来,改完用同一组账号回归。
  5. **不要用管理员账号绕路验证**:超管直通逻辑会掩盖真实链路。验证普通角色时,用普通测试账号,不要临时把运营账号提成管理员。
  6. **处理旧会话**:权限配置改完后,让测试账号重新登录,排除 JWT、Redis 或浏览器缓存的旧快照。线上用户遇到问题时,先引导重新登录,再判断是否还有残留问题。
  7. **更新文档与回归样本**:把最终确认的权限点名称、角色映射和“谁能看什么”写进权限文档或种子数据说明,并保留管理员/运营两个验收账号的回归步骤。

失败反例

这些失败反例要提前避开

  • **反例 1:只给 AI 两张截图,没有请求和权限配置。** “管理员有按钮、运营没有,帮我看看为什么。”没有接口响应、权限点集合和代码位置,AI 只能给出一份“可能原因清单”,最后靠猜修了一处,问题还在。
  • **反例 2:让 AI 直接改前端,把按钮对运营显示。** 提示词写“让运营也能看到导出按钮”,AI 可能在菜单配置里删掉权限判断,但后端接口对运营仍是 403。结果按钮出现了、点不动,用户体验更差,还绕过了前端应有的权限控制。
  • **反例 3:只查前端 v-if,不查后端鉴权。** 按钮不显示就去找前端指令,改完后端一测 403 依旧。权限链路必须前端、后端一起看,因为两者可能用不同权限点,也可能后端本来就不允许。
  • **反例 4:账号没配角色,却当成代码 bug 修。** 运营账号的 user-role 关联是空的,问题出在权限数据。有人为了“快速解决”在代码里写死“运营默认拥有所有按钮”,等于给所有运营账号开了后门,风险极大。
  • **反例 5:用管理员账号对照时忽略超管直通。** 代码里有 `if (user.isAdmin) return true` 的分支,管理员永远通过。拿管理员做参照没问题,但必须意识到普通角色走的可能是完全不同的判断路径,不能据此判断“链路是好的”。
  • **反例 6:测试环境和生产环境混着复现。** 测试环境权限配置已经修过、生产还没同步,两边结论不一致。复现时固定环境、固定账号、固定版本,并记录环境差异,否则定位结果不可信。

主题边界

它和相邻主题的区别

这篇文章解决的是“同一页面、不同角色看到的内容或按钮不同”,核心是角色来源、权限判断、菜单过滤和接口鉴权的链路定位。

本文不解决:设计全新的权限模型、SSO/企业微信/飞书登录配置、安全审计与合规评估,以及越权数据泄露的修复执行。这些都需要安全负责人和权限负责人确认后再进行。

  • 与“页面统计和后台导出对不上”不同:那篇处理的是数据口径与数字差异,这篇处理的是权限可见性和鉴权差异;即使两边数字相同,权限问题依然可能存在。
  • 与“接口偶发 500 的排查”不同:那篇处理的是请求失败、日志和异常堆栈,这篇里接口可能 200 正常返回,只是前端根据权限字段隐藏了按钮,或接口稳定返回 403。
  • 与“补查错误态和空态”不同:那篇是验收阶段的 UI 状态覆盖,这篇是线上权限配置或代码造成的角色差异;权限不足只是其中一种可能,而不是通用验收点。
  • 与“构建失败定位”不同:那篇发生在发版前检查阶段,这篇发生在运行中的权限行为差异,链路和证据完全不同。

可直接套用的流程

1. 先写清楚任务目标:这次要让 AI 帮你完成什么工作,而不是泛泛地问一个问题。

2. 再给资料边界:哪些背景、数据、约束、口径必须被使用,哪些内容不能编。

3. 最后规定输出格式:用清单、表格、方案、话术还是复盘报告,并保留人工检查。

继续看相关教程