必须通过 docs/permission-model.md 明确定义 RBAC 权限模型,再借助 Cursor 生成 AuthContext、受保护路由、按钮级权限控制与一致性校验代码,才能确保路由、菜单、按钮三层权限拦截准确且具备良好的扩展性。

在使用 Cursor 开发 React 项目时,如果把权限判断零散地写进业务代码,不仅容易漏掉边界场景,后续维护、排查和权限调整也会更加困难;但如果完全依赖 AI 自动生成权限逻辑,又可能因为规则理解偏差而出现问题,例如把 admin 和 user 的路由守卫配置写反,或者遗漏按钮级权限校验。想让 Cursor 真正输出可运行、具备权限守卫并方便后续扩展的 React 权限控制方案,前提就是先让它准确理解你的 RBAC 角色模型与权限约束。
第一步:先让 Cursor 准确理解权限模型
打开 Cursor 编辑器,在当前项目根目录新建一个 docs/permission-model.md 文件,用自然语言清楚描述以下三件事:
① 角色定义:ADMIN 可以访问全部页面,并拥有所有按钮操作权限;USER 只能访问 /home、/user,且仅允许点击“编辑资料”按钮;GUEST 仅可访问 /login 和 /public。
② 路由层级:/admin/system 属于最高权限路径,/user/profile 是用户私有页面路径,/public/help 则是公开访问路径。
③ 权限粒度要求:必须同时支持路由守卫、菜单动态渲染、按钮显隐控制这三层权限拦截,不能只实现其中一层。
【关键前提】这个文档必须存在且路径固定,否则 Cursor 很难正确关联上下文并生成一致的权限逻辑。如果删除或改名,后续生成的组件很可能出现权限判断错乱的问题。
第二步:让 AI 生成基于 Context 的权限状态管理
选中刚写好的 docs/permission-model.md 全部内容,右键选择“Ask Cursor”,输入这段指令:“基于这份权限模型,生成一个 React Context,用于管理当前用户角色、权限列表和登录状态,并提供 useAuth hook。要求 useAuth 返回 { userRole, permissions, isLoggedIn, login, logout }。”
这一步生成的 Context 通常会自动包含 token 刷新逻辑以及 sessionStorage 同步机制,相比手动编写往往更完整、更稳妥。生成后请检查 src/contexts/AuthContext.tsx 中是否包含 useEffect(() => { loadFromStorage() }, [])——如果没有,建议手动补上,否则页面刷新后可能会丢失登录状态和权限信息。
生成后的 hook 默认导出名为 useAuth,在 React 组件中直接调用即可,无需再单独封装一层。
第三步:批量生成受保护路由组件
在终端输入:cursor generate --template protected-route --role ADMIN --path /admin/system
Cursor 会自动创建 src/routes/AdminSystemRoute.tsx,并内置完整的路由守卫逻辑:校验 role === 'ADMIN'、验证 token 是否有效、在加载阶段显示骨架屏。如果返回 403,则自动跳转到 /unauthorized 页面。
重复执行这条命令,只需替换 --role 和 --path 参数,即可继续生成 USER 和 GUEST 对应的受保护路由。需要特别注意:不要使用 --role GUEST 去生成 /login 路由,因为登录页本身不应该被权限守卫拦截,否则用户将无法正常进入登录页面。
第四步:用自然语言生成按钮级权限控制
打开 src/pages/UserProfilePage.tsx,在编辑器中高亮“保存修改”按钮所在行 → 右键 → “Ask Cursor” → 输入:“把这个按钮改成权限控制版本:只有 user 角色且 permissions 包含‘edit_profile’时才显示并启用,否则隐藏。”
Cursor 通常会直接把原按钮替换为:{hasPermission('edit_profile') && },并自动注入 const { hasPermission } = useAuth()。
方法一:针对单个按钮做精准改造,适合对已有 React 页面进行快速权限接入。
方法二:在新页面脚手架生成阶段就提前说明需求——例如输入“生成用户管理页,包含搜索框(全员可见)、新增按钮(仅 ADMIN)、导出按钮(ADMIN 和 USER)”,Cursor 往往会一次性生成带有多层权限判断的完整组件。
第五步:强制 AI 校验权限逻辑的一致性
选中整个 src/contexts/AuthContext.tsx 和所有 src/routes/*.tsx 文件 → 右键 → “Ask Cursor” → 输入:“检查这些文件里的权限判断是否全部基于 userRole 字段,是否存在直接用字符串字面量比较 role 的地方(如 role === 'admin'),若有,请统一替换成 useAuth().userRole。”
这一步可以扫描出所有硬编码的角色判断,例如某处写了 if (role === 'admin'),而其他地方却使用 userRole === 'ADMIN'——这种大小写或字段命名不一致的问题,往往会直接导致路由守卫或按钮权限失效。Cursor 会给出替换建议,确认后即可快速完成统一修复。
