# 史诗008:权限角色管理系统 ## 概述 完善系统权限角色管理功能,实现基于角色的权限控制,特别针对广告管理功能添加细粒度权限控制,确保超级管理员可见可操作,普通管理员不可见,提升系统安全性和管理灵活性。 ## 业务背景 当前系统已具备基础的角色和权限实体框架,但实际应用有限: 1. **角色实体存在**:系统已有`Role`实体和`permissions`字段(simple-array类型) 2. **权限中间件存在**:已有`permissionMiddleware`和`checkPermission`函数,但未广泛使用 3. **菜单权限配置存在**:广告管理等菜单已有`permission: 'advertisement:manage'`配置,但未实现实际检查 4. **广告管理无权限控制**:广告模块路由只使用`authMiddleware`,所有登录管理员都可访问 5. **角色定义不清晰**:缺乏明确的超级管理员和普通管理员角色定义和权限分配 为提升系统安全性和管理精细化,需要完善权限角色管理系统,实现真正的基于角色的权限控制。 ## 目标 1. **完善角色权限系统**:定义清晰的超级管理员和普通管理员角色,分配相应权限 2. **实现广告管理权限控制**:广告管理功能仅对超级管理员可见可操作 3. **集成现有权限框架**:充分利用已有的权限中间件和角色实体 4. **前后端权限统一**:实现前端菜单权限控制和后端API权限检查的一致性 5. **数据库默认数据**:添加默认角色和权限数据迁移 6. **专注广告管理**:本次仅实现广告管理权限控制,其他模块权限保持现有状态 ## 范围 ### 包含的功能 1. **角色权限定义完善** (`user-module`增强) - 明确超级管理员(super-admin)和普通管理员(admin)角色定义 - 定义标准权限命名规范(`entity:action`格式) - 添加广告管理相关权限:`advertisement:view`, `advertisement:create`, `advertisement:edit`, `advertisement:delete`, `advertisement:manage` - 本次仅定义广告管理相关权限,其他模块权限保持不变 2. **后端API权限检查增强** (`server`和`advertisements-module`) - 广告模块路由集成`permissionMiddleware`权限检查 - 更新广告管理API,要求`advertisement:manage`权限 - 扩展权限中间件支持基于权限字符串数组检查 - 确保多租户上下文下的权限验证正确性 3. **前端权限控制实现** (`web`管理后台) - 实现菜单项权限过滤:基于用户角色权限隐藏/显示菜单 - 实现路由守卫:无权限用户无法访问受保护页面 - 实现UI组件权限检查:按钮、操作等细粒度控制 - 集成用户权限查询和缓存机制 4. **数据库默认数据** (`user-module-mt`迁移) - 创建默认角色数据:超级管理员、普通管理员 - 分配默认权限集给各角色 - 确保多租户环境下的默认数据一致性 - 提供角色权限管理API供后台使用 5. **测试和数据迁移** - 编写权限检查单元测试和集成测试 - 创建数据库迁移脚本添加默认角色数据 - 验证广告管理权限控制功能 ### 不包含的功能 1. 动态权限管理系统UI(未来可扩展) 2. 角色组和权限继承功能 3. 数据行级权限控制 4. 权限审计日志系统 ## 用户故事 ### 故事1:完善角色权限定义和默认数据 **作为** 系统架构师 **我希望** 明确定义超级管理员和普通管理员角色及其权限 **以便** 为系统提供清晰的权限基础 **验收标准:** - [ ] 在`user-module`中定义标准权限常量:`PERMISSION_ADVERTISEMENT_MANAGE = 'advertisement:manage'`等 - [ ] 创建超级管理员角色:`super-admin`,包含广告管理权限 - [ ] 创建普通管理员角色:`admin`,不包含广告管理权限 - [ ] 权限定义仅针对广告管理,其他模块权限保持现有状态 - [ ] 创建数据库迁移脚本添加默认角色数据到`role`表 - [ ] 提供角色权限管理API:角色列表、权限分配、用户角色分配 - [ ] 编写单元测试验证角色权限逻辑 **优先级**:高 **技术依赖**:`user-module`, `server` ### 故事2:实现后端API权限检查 **作为** 安全工程师 **我希望** 广告管理API进行权限检查 **以便** 防止未授权用户访问广告管理功能 **验收标准:** - [ ] 更新广告模块路由,集成`permissionMiddleware`权限检查 - [ ] 广告列表API:要求`advertisement:view`或`advertisement:manage`权限 - [ ] 广告创建API:要求`advertisement:create`或`advertisement:manage`权限 - [ ] 广告编辑API:要求`advertisement:edit`或`advertisement:manage`权限 - [ ] 广告删除API:要求`advertisement:delete`或`advertisement:manage`权限 - [ ] 广告类型管理API:同样添加权限检查 - [ ] 扩展权限中间件支持权限字符串数组检查(如`checkPermission(['advertisement:manage'])`) - [ ] 确保权限检查在租户上下文中正常工作 - [ ] 编写集成测试验证API权限控制 **优先级**:高 **技术依赖**:`advertisements-module`, `server`, `user-module-mt` ### 故事3:实现前端权限控制 **作为** 后台管理员 **我希望** 菜单和页面根据我的权限动态显示 **以便** 我只看到和访问我有权限的功能 **验收标准:** - [ ] 实现菜单权限过滤:`useMenu`根据用户权限过滤菜单项 - [ ] 广告管理菜单项:仅对拥有`advertisement:manage`权限的用户显示 - [ ] 实现路由守卫:无权限用户访问受保护页面时重定向到404或无权限页面 - [ ] 实现权限检查Hook:`useHasPermission(permission)`返回布尔值 - [ ] 实现UI组件权限包装器:`` - [ ] 集成用户权限查询:用户登录时或定期获取权限列表 - [ ] 权限缓存和状态管理:避免重复查询 - [ ] 编写前端权限控制测试 - [ ] 确保权限变更时UI及时更新 **优先级**:高 **技术依赖**:`web`, `user-module-mt`, `server` ### 故事4:广告管理权限集成测试 **作为** 测试工程师 **我希望** 验证广告管理权限控制功能 **以便** 确保权限系统正确工作 **验收标准:** - [ ] 创建超级管理员测试账号:拥有`advertisement:manage`权限 - [ ] 创建普通管理员测试账号:无`advertisement:manage`权限 - [ ] 后端API测试:验证不同角色访问广告API的结果 - [ ] 前端E2E测试:验证菜单显示和页面访问控制 - [ ] 权限变更测试:验证权限变更后UI及时更新 - [ ] 多租户权限测试:验证租户间的权限隔离 - [ ] 性能测试:验证权限检查对系统性能的影响 - [ ] 安全测试:验证权限绕过漏洞 **优先级**:中 **技术依赖**:所有相关模块 ## 技术设计 ### 数据库设计 ```sql -- 现有role表结构保持不变,用于存储角色和权限 -- 默认角色数据迁移脚本(仅关注广告管理权限) -- 如果角色已存在,则更新权限;如果不存在,则插入 INSERT INTO role (name, description, permissions) VALUES ('super-admin', '超级管理员', ARRAY['advertisement:manage']), ('admin', '普通管理员', ARRAY[]::text[]) ON CONFLICT (name) DO UPDATE SET permissions = CASE WHEN EXCLUDED.name = 'super-admin' THEN -- 超级管理员:确保有 advertisement:manage 权限,保留其他现有权限 array_append(role.permissions, 'advertisement:manage') WHEN EXCLUDED.name = 'admin' THEN -- 普通管理员:确保没有 advertisement:manage 权限,保留其他现有权限 array_remove(role.permissions, 'advertisement:manage') END, description = EXCLUDED.description; -- 用户角色关联表(已存在多对多关系) ``` ### 权限命名规范 采用`entity:action`格式: - `advertisement:view` - 查看广告 - `advertisement:create` - 创建广告 - `advertisement:edit` - 编辑广告 - `advertisement:delete` - 删除广告 - `advertisement:manage` - 广告管理(包含所有操作) ### 模块结构 ``` packages/ ├── user-module/ # 用户模块(增强) │ ├── src/ │ │ ├── constants/ # 新增:权限常量定义 │ │ │ └── permissions.constants.ts │ │ ├── entities/ # 现有:角色实体 │ │ │ └── role.entity.ts │ │ ├── services/ # 现有:角色服务 │ │ │ └── role.service.ts │ │ └── migrations/ # 新增:默认角色数据迁移 │ │ └── 1234567890-add-default-roles.ts │ └── package.json ├── advertisements-module/ # 广告模块(增强) │ ├── src/ │ │ └── routes/ # 更新:集成权限中间件 │ │ └── index.ts │ └── package.json └── server/ # 服务器(增强) ├── src/ │ └── middleware/ # 现有:权限中间件 │ └── permission.middleware.ts └── package.json web/ # 前端管理后台 └── src/ └── client/ └── admin/ ├── hooks/ # 新增:权限相关hooks │ ├── usePermissions.ts │ └── useHasPermission.ts ├── components/ # 新增:权限组件 │ └── RequirePermission.tsx ├── menu.tsx # 更新:菜单权限过滤 └── routes.tsx # 更新:路由守卫 ``` ### API设计 #### 权限相关API(新增/增强) 1. `GET /api/user/permissions` - 获取当前用户权限列表 2. `GET /api/roles` - 获取角色列表(带权限) 3. `PUT /api/roles/{id}/permissions` - 更新角色权限 4. `GET /api/users/{id}/roles` - 获取用户角色 5. `PUT /api/users/{id}/roles` - 更新用户角色 #### 广告管理API(权限保护) 所有广告管理API需要相应权限: - `GET /api/advertisements` - 需要`advertisement:view`或`advertisement:manage` - `POST /api/advertisements` - 需要`advertisement:create`或`advertisement:manage` - `PUT /api/advertisements/{id}` - 需要`advertisement:edit`或`advertisement:manage` - `DELETE /api/advertisements/{id}` - 需要`advertisement:delete`或`advertisement:manage` - 广告类型管理API同理 ### 前端权限控制流程 1. **用户登录** → 获取用户信息和权限列表 2. **权限缓存** → 将权限列表存储在状态管理(Context/Store) 3. **菜单渲染** → `useMenu`根据权限过滤菜单项 4. **路由访问** → 路由守卫检查权限,无权限则重定向 5. **组件渲染** → `RequirePermission`包装器控制组件显示 6. **权限检查** → `useHasPermission`hook用于逻辑判断 ## 集成点 ### 与现有系统集成 1. **用户模块集成**:扩展`user-module`的`RoleService`,添加权限管理方法 2. **广告模块集成**:在`advertisements-module`路由中添加`permissionMiddleware` 3. **服务器集成**:使用现有的`permission.middleware.ts`中间件 4. **前端集成**:扩展`web`管理后台的菜单和路由系统 5. **多租户集成**:确保权限检查在租户上下文中工作 ### 数据流 #### 权限检查流程 1. 用户请求受保护API → `authMiddleware`验证身份 2. → `permissionMiddleware`检查权限 3. → 调用`checkPermission`函数验证用户角色权限 4. → 通过`RoleService.hasPermission()`检查具体权限 5. → 权限通过 → 继续处理请求 6. → 权限拒绝 → 返回403 Forbidden #### 前端权限流程 1. 用户登录成功 → 获取用户权限列表 2. 渲染菜单 → `useMenu`过滤无权限菜单项 3. 页面访问 → 路由守卫检查页面权限 4. 组件渲染 → `RequirePermission`控制组件显示 5. 权限变更 → 重新获取权限,更新UI ## 兼容性要求 1. **API兼容性**:新增权限API,现有API添加权限检查但不改变接口签名 2. **数据库兼容性**:只添加数据不修改表结构,完全向后兼容 3. **UI兼容性**:权限控制透明,不影响现有UI功能 4. **多租户兼容性**:权限系统支持多租户隔离 5. **性能兼容性**:权限检查对系统性能影响最小化 ## 风险与缓解 ### 风险1:权限系统影响现有功能 - **缓解措施**:先在小范围(广告管理)试点,逐步推广 - **验证机制**:充分测试现有功能不受影响 - **回滚方案**:可临时禁用权限检查中间件 ### 风险2:前端权限缓存不一致 - **缓解措施**:实现权限缓存失效机制,定时刷新 - **同步机制**:权限变更时通知前端更新 - **降级方案**:缓存失败时重新获取权限 ### 风险3:多租户权限隔离问题 - **缓解措施**:确保权限检查在租户上下文中进行 - **测试策略**:编写多租户权限隔离测试 - **监控机制**:监控跨租户权限访问尝试 ### 风险4:性能瓶颈 - **缓解措施**:权限列表缓存,避免重复数据库查询 - **优化策略**:批量检查权限,减少数据库访问 - **性能监控**:监控权限检查耗时 ## 测试策略 ### 单元测试 - 角色权限逻辑测试:`RoleService.hasPermission()` - 权限中间件测试:`permissionMiddleware`和`checkPermission` - 前端权限Hook测试:`useHasPermission`和`usePermissions` - 菜单过滤逻辑测试:`useMenu`权限过滤 ### 集成测试 - API权限检查测试:不同角色访问广告API - 数据库迁移测试:默认角色数据正确性 - 多租户权限测试:租户间权限隔离 - 前后端集成测试:权限信息同步 ### E2E测试 - 超级管理员流程:广告管理完整操作 - 普通管理员流程:验证广告管理不可访问 - 权限变更测试:角色权限变更后UI更新 - 错误场景测试:无权限访问尝试处理 ## 部署计划 ### 阶段1:开发环境部署 1. 更新`user-module`添加权限常量定义 2. 创建数据库迁移脚本添加默认角色 3. 部署权限系统基础框架 ### 阶段2:测试环境验证 1. 广告模块集成权限检查 2. 前端权限控制实现 3. 完整功能测试和集成测试 4. 性能测试和安全测试 ### 阶段3:生产环境部署 1. 执行数据库迁移添加默认角色 2. 部署更新后的各模块 3. 监控权限系统运行状态 4. 监控广告管理权限控制效果 ## 成功指标 1. **功能指标**: - 超级管理员可正常访问和操作广告管理 - 普通管理员无法看到和访问广告管理 - API权限检查正确返回403 Forbidden - 前端菜单和路由权限控制正确 2. **性能指标**: - 权限检查响应时间 < 50ms - 权限缓存命中率 > 90% - 系统整体性能影响 < 5% 3. **安全指标**: - 无权限绕过漏洞 - 权限变更及时生效 - 多租户权限隔离完整 4. **用户体验指标**: - 权限控制对授权用户透明 - 无权限用户获得清晰提示 - 权限变更后UI及时更新 ## 后续优化建议 1. **动态权限管理UI**:提供后台界面管理角色和权限 2. **权限审计日志**:记录权限相关操作便于审计 3. **角色组和继承**:支持角色组和权限继承 4. **数据行级权限**:实现更细粒度的数据权限控制 5. **权限分析报表**:提供权限使用情况分析 --- **创建时间**:2025-12-19 **负责人**:产品经理 **状态**:待开始 **优先级**:高 ## 开发进度 ### 待完成 1. ⏳ **故事1:完善角色权限定义和默认数据** 2. ⏳ **故事2:实现后端API权限检查** 3. ⏳ **故事3:实现前端权限控制** 4. ⏳ **故事4:广告管理权限集成测试** ### 技术实现考虑 1. **多租户支持**:权限系统需完全支持多租户架构 2. **缓存策略**:用户权限信息需要合理缓存 3. **错误处理**:权限检查失败提供清晰错误信息 4. **专注广告管理**:设计仅针对广告管理权限控制,保持简单性 5. **测试覆盖**:确保权限相关逻辑充分测试