路由和权限问题记录
路由存在、菜单权限、按钮权限是三件事:详情页刷新被拦、动态参数匹配失效、白名单前缀误放行的排查思路。
本文是「bylcloud-web 开发问题记录」系列之一。bylcloud-web 是基于 Vue 3 + Vite + Element Plus 的企业后台系统,笔记按「现象、排查、处理、下次注意」记录开发中真实遇到的问题。
记录 1:页面存在,不代表用户能访问
路由守卫里最容易绕的点是:前端路由存在、后端菜单存在、按钮权限存在,这是三件事。
比如某个详情页在 src/router/index.js 里已经注册了,说明前端能加载组件。但如果后端菜单树里没有对应父菜单,用户还是不应该访问。还有些详情页本身不在菜单里,只能从列表页进入,这时又需要看 meta.parentPath。
我当时排查过一种情况:用户点击列表里的详情,页面跳转后提示无权限。最开始以为是按钮权限问题,后来发现是详情页 path 和菜单里的父级 path 对不上。前端查菜单树时拿当前 path 去匹配,当然找不到。
后来处理这类页面时,我会先问自己:
- 这个页面是否应该出现在左侧菜单。
- 如果不出现在菜单,它的父页面 path 是什么。
- 是否需要
meta.permission。 - 刷新详情页时还能不能找到父页面。
记录 2:动态参数会影响权限判断
项目里很多详情页是 xxx-info/:params。权限判断时不能拿完整路径硬匹配菜单,因为真实地址里会带参数。
代码里有一段处理:to.matched[1]?.path 用来判断路由是否存在,另一个 toPathAva 会去掉动态参数部分,用来和后端菜单 path 对比。这个处理很关键。
当时遇到的现象是:从列表点击进去正常,但刷新详情页后被拦截。原因就是刷新后 route path 带参数,菜单树里存的是不带参数的父级或基础路径。
这类问题的排查方式:
- 打印
to.path、to.fullPath、to.matched。 - 看菜单树里的 path 到底是什么。
- 看详情页是否配置了
parentPath。 - 判断应该匹配当前 path 还是父级 path。
记录 3:白名单不能只写精确路径
问卷答题、隐私政策、部分数据展示页不走普通登录和菜单权限,所以加了白名单。这里踩过一个细节:白名单如果只用 includes(to.path),带 id 的公开页面就会失败。
比如问卷答题页面实际访问是 /QuestionnaireAnswer/1925076095895465985,白名单里如果只写 /QuestionnaireAnswer,精确匹配会失败。后来需要同时判断 startsWith。
这类页面加白名单时要注意:
- 是否有动态 id。
- 是否允许未登录访问。
- 是否只允许某个前缀访问。
- 会不会误放行同前缀下不该公开的页面。
记录 4:按钮权限不要和菜单权限混着查
basicStore.handleButton 是判断按钮权限的。很多页面操作按钮、详情入口、导出入口都依赖它。最开始我有时会把菜单权限和按钮权限混在一个判断里,结果问题变得不好查。
后来更清楚的分法是:
- 菜单权限决定能不能进模块。
- 路由存在性决定是不是 404。
- 按钮权限决定具体操作能不能点。
如果详情页本身也需要权限,就通过 meta.permission 表达。这样排查时至少知道是哪一层拦住了用户。
