必须调用 invalidateCache() 清除 authManager 缓存,否则 Yii::$app->user->can() 仍返回旧结果;assign() 仅绑定角色不自动同步子权限,需用 addChild() 显式挂载;角色 status=0 默认禁用,须设为1才生效。

权限数据改了但用户没生效,先清缓存再查 authManager
Yii 的 RBAC 权限检查默认走缓存,哪怕你用 AuthManager::assign() 或 AuthManager::remove() 改了数据,Yii::$app->user->can() 还是可能返回旧结果。不是逻辑写错了,是缓存没刷新。
- 每次修改完权限(增删角色、分配/撤回权限),必须手动清掉
authManager缓存:Yii::$app->authManager->invalidateCache();
- 如果你用了 Redis 或 APCu 做缓存组件,确认
authManager配置里cache指向的是那个组件;否则invalidateCache()什么都不会做 - 开发时可以临时关掉缓存:在配置里把
'cache' => null,上线前记得改回来
AuthManager::assign() 只绑定角色,不递归同步子权限
很多人以为调一次 assign() 就把整个角色树的权限都给了用户,其实它只记录「用户 → 角色」这条关系。后续 can() 能否通过,取决于角色是否已关联到具体 Permission(即 Rule 或 Permission 本身)。
- 角色(
Role)必须提前用addChild()显式挂载权限项,比如:$auth->addChild($adminRole, $manageUserPerm);
- 如果角色继承了另一个角色(如
editor继承viewer),也要用addChild()显式声明,RBAC 不自动推导继承链 - 动态分配时别漏掉「角色未激活」这个坑:新创建的角色默认
status = 0(禁用),得手动设status = 1才能被识别
用数据库驱动时,ItemChild 表更新不及时导致权限错乱
当你用 DbManager,所有父子关系(角色→权限、角色→角色)都存在 auth_item_child 表里。直接 SQL 改表或跳过 AuthManager API 操作,很容易让内存状态和 DB 不一致。
- 永远优先用
$auth->addChild($parent, $child)和$auth->removeChild($parent, $child),而不是手写INSERT/DELETE - 批量更新权限时,别在一个事务里混用
assign()和裸 SQL;AuthManager内部有自己的一套缓存键生成逻辑,SQL 直接改表它不知道 - 线上排查权限异常,第一反应不是查用户表,而是查
auth_assignment(谁绑了啥角色)、auth_item_child(角色包含哪些权限)这两张表的数据是否和代码逻辑对得上
自定义 Rule 类里访问不到 $params?检查 execute() 参数签名
动态权限常靠 Rule 实现(比如「只能编辑自己发布的文章」),但很多人写完 execute() 方法发现 $params 总是空数组——其实是方法签名写错了。
-
Rule::execute()必须接收四个参数:$user, $item, $params,第四个才是你要传的业务参数;少一个或顺序错,Yii 就不会传值 - 调用
can()时传参要带键名:Yii::$app->user->can('updatePost', ['post' => $post]),不能只传$post -
Rule类必须注册进authManager配置,且类名和auth_item.rule_name字段严格一致;大小写、命名空间错一个字符,就静默失败


















