yii2.0.43控制器权限控制须同时使用AuthManager+accessControl或动态can()校验;behaviors[‘access’]失效主因是roles缺’@’登录前提或actions写错方法名(应为’index’而非’actionIndex’),且rules匹配顺序影响结果,前端元素也需用can()控制显隐。

Yii2.0.43 的控制器动作权限控制,必须走 AuthManager + AccessControl 或动态 can() 校验双路径,只配路由或只写行为规则都不保险。
为什么 behaviors()['access'] 配了却没生效?
常见错误是只写了 roles 却漏掉 '@' 的登录前提,或把控制器方法名写错(比如写成 actionIndex 而不是 index)。
-
rules中的actions数组值必须是动作 ID(小写、无action前缀),例如['index', 'delete'],不是['actionIndex', 'actionDelete'] - 如果用户未登录,
['@']会自动跳转到loginUrl;但若你自定义了User组件且identityClass返回 NULL,@就永远不匹配 - 多个
rules是“从上到下匹配首个成功项”,顺序写反(比如把['allow'=>false]放前面)会导致全放行
can() 动态校验该在哪儿写?
不能只靠 behaviors 拦住入口,按钮、链接、Gridview 操作列这些前端可见元素,必须用 Yii::$app->user->can('post/update') 控制显隐——否则权限只是“纸糊的门”。
- 在视图里判断:
<?php if (Yii::$app->user->can('post/delete')): ?><a href="https://www.php.cn/link/310b60949d2b6096903d7e8a539b20f5'delete',%20'id'=>%24model->id])%20?>">删</a><?php endif; ?> - 在
GridView::widget()的columns中嵌套判断,避免渲染无权操作的按钮 - 注意:每次调用
can()都会查缓存或 DB,高频页面建议用AuthManager::checkAccess()批量预查,或开启PhpManager的文件缓存(但开发期要记得清rbac/目录)
DbManager 迁移失败或权限不生效的三个硬坑
用数据库存 RBAC 数据时,yii migrate --migrationPath=@yii/rbac/migrations/ 看似简单,实际卡点极多。
- 迁移前没配好
authManager的itemTable等字段,会导致表建错(如建出auth_item却查auth_items) - 执行迁移后,
auth_assignment表里user_id必须是整型(不是字符串),否则assign()成功但can()返回 false - 分配角色时用了
$auth->assign($role, '1')(字符串 ID),而 user 表主键是 int,类型不匹配就静默失败——务必用(int) $userId
RBAC 最容易被绕过的环节,从来不是配置多复杂,而是「前端藏按钮」和「后端不二次校验」。哪怕你用 DbManager 把权限表建得再漂亮,控制器里漏掉一行 if (!Yii::$app->user->can('order/export')) throw new ForbiddenHttpException();,导出接口就裸奔了。