1651 字
8 分钟
- 次浏览
后台页面不能只靠菜单藏入口
读前导览

公开页、登录后页面和管理员页面要在 router meta 和导航守卫里分清楚。接口权限交给后端兜底。

正文
1651 字
阅读
8 分钟
结构
8 节
来源线索

sub2api/frontend-router

sub2api:frontend-router-readme sub2api:vue-router-guards sub2api:admin-route-meta

后台页面很容易从菜单开始做。

先有一个侧边栏,再把用户管理、分组管理、账号管理、代理管理、兑换码管理这些入口塞进去。普通用户看不到管理员菜单,管理员能看到更多按钮。界面上看起来,权限好像已经做完了。

更合理的顺序是反过来:先写路由守卫,再做菜单。

菜单只是入口。一个页面到底能不能到达,应该由路由表、route meta、导航守卫和后端校验一起决定。

路由表先分三层#

一个管理后台最起码要把页面分成三类。

第一类是公开页面,比如登录和注册。它们不需要认证,甚至要阻止已登录用户反复进入。

第二类是普通用户页面,比如 dashboard、API key、usage、兑换和个人资料。它们需要登录,但不需要管理员角色。

第三类才是管理员页面,比如用户、分组、账号、代理和兑换码管理。它们不仅需要登录,还需要管理员角色。

这三类如果只在组件里临时判断,很快就会散掉。更稳的是把它们先写进路由表:

public route -> requiresAuth: false
user route -> requiresAuth: true
admin route -> requiresAuth: true + requiresAdmin: true

这样菜单、面包屑、标题和权限判断都能从同一份路由元信息里长出来,而不是每个页面各写一套理解。

守卫挡不住绕过,但能减少误入#

前端路由守卫不能代替后端鉴权。

这一点要先说清楚。浏览器里的任何判断都可以被绕过,token 校验、角色校验和接口权限必须在后端完成。

前端守卫仍有它该做的事。

它负责先把常见误入挡住:

  • 没登录访问受保护页面,跳回登录页。
  • 已登录再访问登录页,回到 dashboard。
  • 普通用户访问管理员页面,回到普通入口。
  • 登录前想去的地址,用 redirect query 记住。
  • 页面标题跟着 route meta 更新。

这些动作挡不住恶意请求,主要是让正常用户少遇到空白页、接口 401、半加载页面或突然消失的菜单。

后端照样验权限;前端只把正常访问流程接顺。

菜单应该读路由,不该自造权限#

后台菜单最怕另起一套配置。

路由里写了一份管理员页面,菜单里又写一份管理员页面,面包屑再写一份,页面标题再写一份。短期好改,长期一定会漂移。

更好的做法是让菜单尊重 route meta。

比如路由元信息里已经有:

  • requiresAuth
  • requiresAdmin
  • title
  • breadcrumbs
  • icon
  • hideInMenu

菜单就不需要重新发明权限判断。它只负责把“当前用户能看到的、没有隐藏的路由”展示出来。

这样新增一个管理员页面时,流程很明确:加 route,写 meta,接组件,更新文档。菜单只是自然跟上,而不是另一个需要手工同步的地方。

懒加载是小服务器友好的默认设置#

个人服务的后台不该一上来就把所有页面都打进首屏。

dashboard、keys、usage、profile、admin/users、admin/accounts,这些页面并不是每个用户每次都会打开。用动态 import 做懒加载,首屏 bundle 会更轻,普通用户也不用为管理员页面付出首屏成本。

这主要是很现实的资源约束。

服务器只负责静态文件和 API,本来就不该为了一个管理后台增加太多前端负担。Vite 和 Vue Router 已经能把路由组件拆开,就顺手用好。

对个人站和小后台来说,性能优化不一定是复杂缓存。很多时候,先别把用不到的页面塞进首屏,就已经够有效。

redirect query 是小细节,也是状态交代#

没有登录时访问 /admin/users,系统不能只说“你没权限”。

更自然的流程是:先跳到登录页,并把原始目标放进 redirect query。登录成功后,如果用户确实有权限,再回到原目标;如果没有权限,再落到普通 dashboard。

这个细节很小,但能让用户登录后不必重新找入口。

没有 redirect,用户登录后还要自己重新找入口。对后台工具来说,这种摩擦很容易被忽视,但每天用就会烦。

404 和刷新也属于路由设计#

路由 README 里提到一个常见问题:刷新页面时 404。

这是单页应用的老问题。用户直接访问一个前端路由,服务器如果不知道要回 index.html,就会把它当成真实文件路径处理。

所以路由设计不只在前端。部署层也要配合:

unknown frontend route -> index.html
api route -> backend
static asset -> file

否则本地开发一切正常,线上刷新就炸。很多后台看起来是前端问题,实际是部署层没有理解 SPA 路由。

新增页面要有一条固定路径#

把新增后台页面的步骤固定下来是个好习惯:

  1. 在 routes 数组里加路由定义。
  2. 创建 view 组件。
  3. 设置 requiresAuth / requiresAdmin
  4. 用动态 import 懒加载组件。
  5. 更新路由文档。

这条流程很朴素,但它能避免后台越来越像临时拼出来的页面集合。

尤其是管理员页面,不能因为“只是加一个入口”就跳过 meta。没有 meta,菜单不知道怎么展示;没有 role 标记,守卫不知道怎么拦;没有文档,后续维护者不知道这个页面属于哪一层。

前端能拦,后端必须再验#

最后还是要回到安全问题。

前端守卫可以让普通用户不进入管理员视图,但它不能证明接口安全。用户可以直接请求 API,也可以篡改前端状态。所以后台接口必须每次验证 token,必须在服务端判断 admin role,不能相信前端路由已经拦过。

所以路由说明里那句 client-side only 不能省。

前端守卫负责减少误入和改善体验;后端校验负责授权。菜单、路由、接口三层各管一段,后台才不容易在功能变多后变形。

后台页面不是先把菜单画出来就完了。

先把路由表写清楚,菜单才不会被迫变成权限系统的替身。

后台页面不能只靠菜单藏入口
https://blog.sunmmyapi.xyz/posts/frontend-admin-route-guards-before-menu/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容