Files
crawler-plugin/docs/specs/02-session-menu-permission.md
T

3.4 KiB

02 登录态、菜单树与菜单级权限

模块职责

负责后台 Vue 启动时的当前用户加载、菜单树加载、Cookie/Session 复用、路由级菜单权限判断、退出登录和未登录处理。本模块只处理菜单/页面级权限,不处理按钮级权限。

依赖关系

上游:Java AdminAuthSupportAdminConsoleController.currentUserAdminConsoleController.currentUserMenusPermissionMenuService.getUserColumnPermissions

下游:AdminLayout、Vue Router 守卫、所有页面权限元数据。

数据表:columnsuser_column_permissionusers

核心接口:原实现 → 目标实现

接口/符号 原实现 目标实现
当前用户 Flask get_admin_current_user 或 Java AdminConsoleController.currentUser Java GET /api/admin/current-user,维持 {item} 语义
菜单 Flask get_admin_current_user_menus 返回扁平项;Java同样返回扁平项 Java GET /api/admin/current-user/menus 返回树形 items
登出 admin.js 直接 fetch /api/admin/logout api/session.ts:logout,由 Pinia action 调用
权限展开 Flask _effective_permission_sets 或 Java PermissionMenuService 统一由 Java PermissionMenuService 完成
前端权限 hasAdminTabAccessapplyTabAccess Router guard 比较 route.meta.menuKey 和菜单树 key

目标菜单契约

菜单节点:

  • key:稳定的 columns.column_key
  • name:展示名称。
  • route:相对于 /admin-vue/ 的页面路径,例如 account/users
  • children:分组节点和页面节点的层级。
  • sort:后端排序字段;前端按后端顺序展示,不二次重排。

分组节点可以没有 route;页面节点必须有 route 才能进入页面。

内部结构

admin-session store
├── user
├── menuTree
├── initialized
├── loading
└── error

初始化顺序
1. GET /api/admin/current-user
2. GET /api/admin/current-user/menus
3. 保存用户和菜单树
4. Router guard 校验目标页面
5. 无目标路径时进入第一个可见页面

Cookie 规则:

  • 请求使用同源 Cookie/Session。
  • 前端不保存密码、JWT 或长期敏感凭证。
  • Axios withCredentials 必须开启。
  • 401 统一跳转 /login,并携带当前目标路径作为 redirect 信息;是否实际接受 redirect 参数由登录模块决定。

类型映射

原字段 目标字段
route_path route
column_key key
parent_id children 关系
adminCurrentUsername AdminUser.username
currentUserRole AdminUser.role
adminTabs AdminMenuNode[]

迁移/实现注意事项

  1. 后端必须先过滤当前用户的有效菜单,再组装树,不能把全量菜单发给前端后让前端过滤。
  2. 超级管理员可以获得全部 admin 菜单,但仍应通过同一树形 DTO 返回。
  3. 页面权限只控制菜单可见性和路由进入;具体 API 继续由 Java 后端鉴权。
  4. 不新增按钮级 actions 字段,不新增 action 权限表。
  5. 不保留 X-Admin-Menu-Format 双格式,不根据 User-Agent、查询参数或调用方返回不同菜单结构。
  6. column_key 继续作为稳定权限 key,Flyway 只迁移 route_path,避免现有 Java 业务权限常量失效。
  7. 菜单树为空时必须区分“权限为空”和“接口失败”,不能把接口失败误显示为无权限。