不能用单角色外键字段(如 role_id),因为无法支持用户多角色(如编辑+审核员),导致权限查询遗漏、扩展用户组时权限叠加混乱;必须用中间表实现多对多关系。

CodeIgniter 框架里做 RBAC,表结构不能照搬通用设计——sys_user_role 这类“用户-角色”关联表必须支持多角色,否则管理员加个审计角色就失效;而“用户组权限”若强行塞进同一套关联逻辑,会直接导致权限叠加混乱。
为什么不能用单角色外键字段(如 role_id)?
CI 项目常从简单开始,有人直接在 users 表加 role_id 字段,以为一个用户只配一个角色。这会导致:
- 无法实现“用户同时是编辑+审核员”的真实场景
-
getUserPermissions()只查一条角色,漏掉其他角色的权限 - 后续扩展用户组(group)时,权限来源变成“用户个人角色 + 所属组角色”,但单字段根本存不下
正确做法是拆出独立的中间表,哪怕初期只用一个角色,也要预留多对多能力。
user_group 和 group_role 表要不要加?
要加,但不是必须立刻启用。很多 CI 项目卡在这一步:要么全不用组,要么一上来就堆四张表,结果 group_role_permission 里全是空数据。实际建议:
- 先建
user_groups和user_group_member(用户和组的多对多) - 再建
group_roles(组可分配哪些角色),复用已有roles和role_permissions表 - 权限聚合逻辑统一走
getUserPermissions($userId):查该用户所有直连角色 + 所属组对应的所有角色 → 合并去重权限码 - 避免新增
group_permissions表——它和role_permissions语义重复,徒增同步负担
permission 表的 resource_type 字段怎么填才不翻车?
这个字段决定权限校验时能否精准匹配。CI 的钩子或过滤器(如 post_controller_constructor)靠它分流处理,填错就白校验。常见错误:
- 把菜单和按钮都标成
MENU,结果按钮点击没拦截 - API 接口权限写成
API,但校验逻辑只认HTTP或ROUTE - 前端传来的权限码是
article:edit,后端却按resource_type='BUTTON'去查,而实际存的是OPERATION
推荐值固定为:MENU(左侧导航/顶部菜单)、BUTTON(页面内操作按钮)、API(接口路径,如 /api/v1/orders)、ELEMENT(DOM ID 或 class,用于 JS 控制显隐)。校验前务必确认前端请求携带的权限标识与该字段值能对上。
CI 钩子中权限校验失败,为什么日志里看不到具体哪条权限缺失?
因为默认 log_threshold 设为 1(只记 Error),而权限拒绝通常走 show_403() 或跳转,不触发 PHP error。解决方法:
- 在
rbac_hook.php的aoto_verify()里加一行:log_message('debug', "User {$userId} denied access to {$currentRoute}, missing permission: {$requiredPerm}"); - 确保
config/config.php中$config['log_threshold'] = 4;(DEBUG 级别) - 检查
application/logs/目录权限,CI 默认用0644,Web 服务器需有写入权
最易被忽略的是:权限码字符串大小写敏感,order:create 和 ORDER:CREATE 在数据库里是两条记录,校验时一个字母不对就静默失败。

















