yii rbac权限配置核心三步:建表、写角色权限关系、绑用户;缺一步则$this->can()恒返回false。需配dbmanager、执行迁移建四表、代码初始化角色权限、清缓存、id为int、权限名合法。

Yii 做权限管理系统,RBAC 配置核心就三步:建好表、写好角色权限关系、绑好用户。跳过任意一步,$this->can('xxx') 就会一直返回 false,还不报错——这是最常踩的坑。
先配 DbManager 并生成四张表
Yii2 默认不启用 RBAC,必须手动配置数据库驱动并建表,PhpManager 仅适合本地试跑,别上生产环境。
- 在
console/config/main.php和backend/config/main.php(或common/config/main.php)的components中都加上:
'authManager' => ['class' => 'yii\rbac\DbManager']
- 确认数据库连接已配置(检查
common/config/main-local.php中的db组件),且账号有建表权限; - 在项目根目录执行迁移命令:
yii migrate --migrationPath=@yii/rbac/migrations - 迁移后立刻进数据库检查是否存在以下四张表:
auth_item(存角色/权限)、auth_item_child(父子关系)、auth_assignment(用户分配)、auth_rule(动态规则);
缺一张,后续 assign 或 can 全部静默失效。
用代码初始化角色与权限
不要依赖后台界面点来点去,所有结构用 PHP 代码定义,方便版本管理、多环境同步。
- 新建
console/controllers/RbacController.php,在actionInit()中写:
① 获取实例:$auth = Yii::$app->authManager;
② 创建权限(name 只能含字母、数字、下划线、短横线):
$createPost = $auth->createPermission('create_post');<br>
$createPost->description = '创建文章';<br>
$auth->add($createPost);
③ 创建角色:
$author = $auth->createRole('author');<br>
$author->description = '作者';<br>
$auth->add($author);
④ 绑定权限到角色:$auth->addChild($author, $createPost);
⑤ 设置继承(如 editor 继承 author):
$editor = $auth->createRole('editor');<br>
$auth->add($editor);<br>
$auth->addChild($editor, $author);
⑥ 分配角色给用户(注意:userId 必须是 int 类型):$auth->assign($author, 1);
验证和避坑要点
配置完不验证,等于没配。常见“明明写了却没权限”的原因基本就这几个:
-
缓存未清:每次增删角色、分配权限后,必须立即调用
Yii::$app->authManager->invalidateCache();
否则can()读的是旧数据; -
ID 类型错误:用户模型中的
getId()方法必须返回int,不能是字符串或 null;传'1'会导致auth_assignment.user_id写成 0; -
字符集问题(MySQL 8+):建库时用 utf8mb4,否则迁移可能失败:
ALTER DATABASE `your_db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -
权限名非法:用
post.create、用户管理这类含点、中文、空格的名字,$auth->add()会静默失败,建议统一小写+下划线,如view_dashboard、export_report。
进阶:加 Rule 实现动态校验
比如“只能编辑自己发布的文章”,需要自定义 Rule 类:
- 新建
rbac/OwnPostRule.php,继承\yii\rbac\Rule,重写execute(); - 注册 Rule:
$rule = new OwnPostRule();<br> $auth->add($rule);
- 创建带 rule 的权限:
$updateOwnPost = $auth->createPermission('update_own_post');<br> $updateOwnPost->ruleName = $rule->name;<br> $auth->add($updateOwnPost); - 再把该权限加给角色即可。











