简介
本文件为 DouPHP 后台“角色管理”能力的权威说明,覆盖管理员角色定义与分类、权限继承机制、角色与菜单/操作权限的绑定关系,以及角色的创建、编辑、删除流程与界面操作指南。文档同时提供最佳实践与安全建议,帮助管理员安全、可控地分配后台访问权限。
项目结构
角色管理在后台模块中由控制器、服务、模型、中间件与菜单服务共同实现:
- 控制器负责页面渲染与请求路由;
- 服务封装业务逻辑(新增/更新/删除、权限列表构建、日志查询);
- 模型负责数据持久化;
- 中间件与授权门控负责访问控制;
- 菜单服务提供基础菜单键集合,用于权限勾选与鉴权映射。
graph TB
A["管理员浏览器"] --> B["权限中间件<br/>PermissionMiddleware"]
B --> C["授权门控<br/>AdminGate"]
C --> D["菜单服务<br/>AdminMenuService"]
B --> E["管理器控制器<br/>ManagerController"]
E --> F["管理器服务<br/>ManagerService"]
F --> G["管理员模型<br/>Manager"]
F --> H["配置<br/>module.php"]
图表来源
- admin/middleware/PermissionMiddleware.php:25-72
- admin/service/authorization/AdminGate.php:23-91
- admin/service/menu/AdminMenuService.php:23-55
- admin/controller/manager/ManagerController.php:30-175
- admin/service/manager/ManagerService.php:33-608
- admin/model/manager/Manager.php:25-217
- config/module.php:1-132
章节来源
- admin/controller/manager/ManagerController.php:30-175
- admin/service/manager/ManagerService.php:33-608
- admin/model/manager/Manager.php:25-217
- admin/middleware/PermissionMiddleware.php:25-72
- admin/service/authorization/AdminGate.php:23-91
- admin/service/menu/AdminMenuService.php:23-55
- config/module.php:1-132
核心组件
- 管理员控制器:提供管理员列表、新增、编辑、删除、日志等页面入口,并调用服务完成业务处理。
- 管理员服务:实现新增/更新/删除、权限勾选列表生成、日志筛选与分页、模块选项生成等。
- 管理员模型:维护 admin 表记录,提供账号查找、密码重置、登录失败统计等能力。
- 权限中间件:校验当前管理员是否可访问当前模块与动作。
- 授权门控:判定超级管理员放行、自定义角色按 action_list 白名单匹配,并支持子资源到父资源的鉴权别名映射。
- 菜单服务:提供框架基础菜单键集合,用于权限勾选与鉴权映射。
- 模块配置:声明列式模块与单页模块,决定权限勾选范围与可见性。
章节来源
- admin/controller/manager/ManagerController.php:30-175
- admin/service/manager/ManagerService.php:33-608
- admin/model/manager/Manager.php:25-217
- admin/middleware/PermissionMiddleware.php:25-72
- admin/service/authorization/AdminGate.php:23-91
- admin/service/menu/AdminMenuService.php:23-55
- config/module.php:1-132
架构总览
后台访问控制链路如下:
- 请求进入后,先经权限中间件检查登录态与模块访问权限;
- 授权门控根据管理员类型与 action_list 决定是否放行;
- 若通过,进入对应控制器与服务层进行业务处理;
- 菜单服务与模块配置共同决定权限勾选项与可见范围。
sequenceDiagram
participant U as "管理员"
participant M as "权限中间件"
participant G as "授权门控"
participant C as "管理器控制器"
participant S as "管理器服务"
participant DB as "数据库"
U->>M : 访问后台模块
M->>G : canAccess(管理员, 模块, 动作, 目标ID)
alt 超级管理员或白名单命中
G-->>M : true
M->>C : 继续处理
C->>S : 业务方法
S->>DB : 读写数据
DB-->>S : 结果
S-->>C : 返回数据
C-->>U : 响应页面
else 无权限
G-->>M : false
M-->>U : 重定向至首页
end
图表来源
- admin/middleware/PermissionMiddleware.php:45-72
- admin/service/authorization/AdminGate.php:53-91
- admin/controller/manager/ManagerController.php:62-175
- admin/service/manager/ManagerService.php:114-290
详细组件分析
角色定义与分类
- 超级管理员:action_list 为 ALL,拥有全部后台模块访问权限。
- 普通管理员:action_list 为 ADMIN,具备受限但较宽泛的权限(具体以系统内置策略为准)。
- 自定义管理员:action_list 为逗号分隔的模块白名单,仅能访问被勾选的模块。
- 自身资料编辑豁免:自定义管理员可编辑本人资料(manager/edit/update),无需额外权限。
上述分类与豁免逻辑由授权门控与控制器/服务中的权限判断共同实现。
章节来源
- admin/service/authorization/AdminGate.php:53-91
- admin/service/authorization/AdminGate.php:93-122
- admin/controller/manager/ManagerController.php:77-93
- admin/service/manager/ManagerService.php:92-112
权限继承与优先级
- 子资源到父资源的鉴权别名映射:当访问子资源时,会映射到父模块进行权限判定,确保父模块权限对子资源透明继承。
- 优先级:超级管理员 > 自定义管理员白名单 > 默认拒绝。
- 自身资料编辑豁免优先于白名单限制。
flowchart TD
Start["开始"] --> Type{"管理员类型"}
Type --> |ALL| AllowAll["放行"]
Type --> |ADMIN| CheckDefined["按内置策略判定"]
Type --> |DEFINED| MapSub["子资源映射到父模块"]
MapSub --> CheckList["检查 action_list 是否包含父模块"]
CheckList --> |是| Allow["放行"]
CheckList --> |否| Deny["拒绝"]
CheckDefined --> SelfEdit{"是否编辑本人资料?"}
SelfEdit --> |是| Allow
SelfEdit --> |否| Deny
图表来源
- admin/service/authorization/AdminGate.php:31-51
- admin/service/authorization/AdminGate.php:53-91
- admin/service/authorization/AdminGate.php:93-122
章节来源
- admin/service/authorization/AdminGate.php:31-91
- admin/service/authorization/AdminGate.php:93-122
角色与菜单/操作权限绑定
- 权限勾选范围来源于:
- 列式模块(column_module)及其分类项;
- 单页模块(single_module);
- 框架基础菜单键(basicMenu)。
- 模块可见性与隐藏规则由配置 module.php 控制。
- 权限勾选列表在服务层组装,并在模板中以复选框呈现。
classDiagram
class AdminMenuService {
+basicMenu() array
}
class ManagerService {
+adminActionList(admin_id) array
+moduleOptions() array
}
class Config {
+get(key) mixed
}
AdminMenuService <.. ManagerService : "提供基础菜单键"
ManagerService --> Config : "读取模块配置"
图表来源
- admin/service/menu/AdminMenuService.php:23-55
- admin/service/manager/ManagerService.php:542-608
- config/module.php:1-132
章节来源
- admin/service/manager/ManagerService.php:542-608
- admin/service/menu/AdminMenuService.php:23-55
- config/module.php:1-132
角色创建流程
- 入口:管理员列表页点击“新增”。
- 表单字段:用户名、邮箱、密码、确认密码、角色类型(超级管理员/普通管理员/自定义)、自定义权限勾选。
- 权限校验:仅超级管理员可新增管理员。
- 提交后:服务层校验并写入数据,成功后跳转至编辑页。
sequenceDiagram
participant U as "管理员"
participant C as "管理器控制器"
participant S as "管理器服务"
participant DB as "数据库"
U->>C : 打开新增页
C->>C : 校验当前管理员是否为超级管理员
C->>S : 获取权限勾选列表
S-->>C : 返回权限列表
C-->>U : 渲染新增表单
U->>C : 提交新增
C->>S : insert(data)
S->>DB : 写入管理员记录
DB-->>S : 成功
S-->>C : 返回新ID
C-->>U : 跳转编辑页
图表来源
- admin/controller/manager/ManagerController.php:77-109
- admin/service/manager/ManagerService.php:114-158
章节来源
- admin/controller/manager/ManagerController.php:77-109
- admin/service/manager/ManagerService.php:114-158
- admin/view/manager.htm:46-100
角色编辑流程
- 入口:管理员列表点击“编辑”。
- 权限校验:仅超级管理员可编辑他人;非超级管理员只能编辑本人。
- 表单字段:用户名(受权限限制)、邮箱、旧密码(如需修改密码)、新密码、角色类型、自定义权限勾选。
- 提交后:服务层校验旧密码与权限,更新数据并记录日志。
sequenceDiagram
participant U as "管理员"
participant C as "管理器控制器"
participant S as "管理器服务"
participant DB as "数据库"
U->>C : 打开编辑页
C->>C : 校验是否允许编辑该管理员
C->>S : 获取权限勾选列表
S-->>C : 返回权限列表
C-->>U : 渲染编辑表单
U->>C : 提交更新
C->>S : update(data)
S->>DB : 更新管理员记录
DB-->>S : 成功
S-->>C : 返回
C-->>U : 提示成功并回退
图表来源
- admin/controller/manager/ManagerController.php:115-160
- admin/service/manager/ManagerService.php:160-243
- admin/view/manager.htm:102-165
章节来源
- admin/controller/manager/ManagerController.php:115-160
- admin/service/manager/ManagerService.php:160-243
- admin/view/manager.htm:102-165
角色删除流程
- 入口:管理员列表点击“删除”。
- 二次确认:首次请求显示确认信息;再次提交执行删除。
- 权限校验:仅超级管理员可删除;禁止删除自己。
- 提交后:服务层记录日志并删除记录。
sequenceDiagram
participant U as "管理员"
participant C as "管理器控制器"
participant S as "管理器服务"
participant DB as "数据库"
U->>C : 触发删除
C->>S : delete(id, post)
alt 未确认
S-->>C : 返回确认信息
C-->>U : 显示确认页
U->>C : 提交确认
C->>S : delete(id, confirm=true)
S->>DB : 删除记录
DB-->>S : 成功
S-->>C : 返回成功消息
C-->>U : 返回列表
else 已确认
S->>DB : 删除记录
DB-->>S : 成功
S-->>C : 返回成功消息
C-->>U : 返回列表
end
图表来源
- admin/controller/manager/ManagerController.php:166-175
- admin/service/manager/ManagerService.php:245-290
章节来源
- admin/controller/manager/ManagerController.php:166-175
- admin/service/manager/ManagerService.php:245-290
权限分配界面与操作指南
- 新增/编辑页的角色类型下拉框:超级管理员/普通管理员/自定义。
- 选择“自定义”后,出现复选框组,列出所有可分配的模块(含列式模块与其分类、单页模块、基础菜单键)。
- 勾选所需模块后提交,系统将把模块短名写入 action_list。
- 注意:部分模块可能因配置隐藏而不出现在列表中。
章节来源
- admin/view/manager.htm:73-94
- admin/view/manager.htm:137-158
- admin/service/manager/ManagerService.php:542-608
- config/module.php:1-132
依赖关系分析
- 控制器依赖服务;服务依赖模型与配置;中间件依赖授权门控;授权门控依赖菜单服务与配置。
- 模块配置决定权限勾选范围与可见性;菜单服务提供基础菜单键;授权门控将子资源映射到父资源进行鉴权。
graph LR
Controller["管理器控制器"] --> Service["管理器服务"]
Service --> Model["管理员模型"]
Service --> Config["模块配置"]
Middleware["权限中间件"] --> Gate["授权门控"]
Gate --> Menu["菜单服务"]
Gate --> Config
图表来源
- admin/controller/manager/ManagerController.php:30-175
- admin/service/manager/ManagerService.php:33-608
- admin/model/manager/Manager.php:25-217
- admin/middleware/PermissionMiddleware.php:25-72
- admin/service/authorization/AdminGate.php:23-91
- admin/service/menu/AdminMenuService.php:23-55
- config/module.php:1-132
章节来源
- admin/controller/manager/ManagerController.php:30-175
- admin/service/manager/ManagerService.php:33-608
- admin/model/manager/Manager.php:25-217
- admin/middleware/PermissionMiddleware.php:25-72
- admin/service/authorization/AdminGate.php:23-91
- admin/service/menu/AdminMenuService.php:23-55
- config/module.php:1-132
性能考虑
- 权限勾选列表与服务端模块选项计算仅在新增/编辑页加载时执行,避免频繁 IO。
- 日志查询使用分页与过滤条件,减少大数据量下的渲染开销。
- 建议在模块较多时合理拆分列式/单页模块,降低权限矩阵复杂度。
故障排查指南
- 无法新增管理员:检查当前登录管理员是否为超级管理员。
- 无法编辑他人:检查当前管理员是否为超级管理员;否则仅能编辑本人。
- 删除失败:确认是否尝试删除自己;确认是否已提交二次确认。
- 权限不生效:检查 action_list 是否正确写入;确认子资源是否已在授权门控中登记别名映射;核对模块配置是否隐藏该模块。
- 日志为空或越权:检查非超级管理员的日志查询是否被强制锁定为当前管理员;确认过滤参数是否非法导致空集兜底。
章节来源
- admin/controller/manager/ManagerController.php:77-175
- admin/service/manager/ManagerService.php:114-290
- admin/service/authorization/AdminGate.php:31-91
- admin/service/manager/ManagerService.php:383-467
结论
DouPHP 的角色管理采用“超级管理员/普通管理员/自定义管理员”三类角色,并通过 action_list 白名单与子资源到父资源的鉴权别名映射实现细粒度权限控制。结合权限中间件与授权门控,系统在入口处严格校验访问权限,保障后台安全。通过清晰的创建、编辑、删除流程与直观的权限分配界面,管理员可高效、安全地管理后台角色与权限。
附录
- 最佳实践
- 尽量使用“自定义管理员”进行最小权限分配,避免滥用超级管理员。
- 定期审查管理员列表与权限勾选,及时回收不再需要的权限。
- 对敏感模块(如设置、备份、主题)谨慎授权。
- 启用并定期查看管理员操作日志,发现异常行为及时处理。
- 安全建议
- 强密码策略与定期更换密码。
- 限制同一 IP 的登录失败次数与锁定时间。
- 避免在日志中记录敏感信息。
- 对子资源新增时同步登记鉴权别名,防止越权访问。