AccessControl规则必须通过behaviors()注册,且规则顺序、动作ID小写(如'index'而非'actionIndex')、登录状态符号(@或?)三者全对才生效;roles为硬性前提,不填则规则永不匹配;only/except默认作用于全部动作;前端按钮需二次校验权限,不能仅依赖AccessControl。

AccessControl 必须通过 behaviors() 注册,且规则顺序、动作 ID 写法、登录状态符号(@ 和 ?)三者错一个,整个规则就失效。
rules 中的 actions 必须写小写动作 ID,不是方法名
比如控制器里定义的是 actionIndex(),但在 rules 的 actions 数组里必须写 ['index'],不能写 ['actionIndex'] 或 ['Index']。大小写敏感,且严格去除 action 前缀。
-
only和except也用小写动作 ID,例如'only' => ['index', 'create'] - 如果写了
'only' => ['actionIndex'],AccessControl 直接忽略该控制器所有动作,相当于没配 - 调试时可临时加
'denyCallback'打印日志,确认是否命中规则
roles 字段不填 @ 或 ? 就等于白配
roles 是硬性前提,不是可选条件。只写 'allow' => true 而不指定 roles,该规则永远不匹配——因为 AccessRule 默认要求角色验证通过才放行。
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
-
['@']表示用户已登录(Yii::$app->user->isGuest === false),未登录会跳转到loginUrl -
['?']表示仅允许游客(isGuest === true),已登录用户会被拒绝 - 若自定义了
User组件,且identityClass::findIdentity()在用户不存在时返回null,@永远不成立 - 多个
rules是“从上到下取第一个匹配项”,把['allow' => false]放最前面,后面全被拦掉
没配 only 或 except 时,规则默认作用于全部动作
很多人以为不写 only 就只管列出的 actions,其实不是:only 是白名单,except 是黑名单,都不写则规则对当前控制器所有动作生效。
- 想只限制
update和delete,其他动作开放,得明确写'except' => ['update', 'delete'],再配一条专管这两个动作的rules - 想只让游客访问
login和error,其他都要求登录,推荐写两段规则:一段roles => ['?']+actions => ['login', 'error'],一段roles => ['@']+actions => ['logout', 'index'] -
only和rules中的actions是两个独立筛选层:先由only/except确定哪些动作进过滤器,再由rules判定放行/拒绝
前端按钮和链接必须二次校验,不能只靠 AccessControl 拦后端
AccessControl 只管控制器入口,拦不住直接发请求的用户。只要 URL 和参数能猜出来,绕过前端 UI 一击即中。
- 视图中显示删除按钮前,必须用
Yii::$app->user->can('post/delete')判断,不能只靠AccessControl拦actionDelete - GridView 的操作列要嵌套判断:
'class' => ActionColumn::className(), 'template' => '{view} {update} {delete}', 'buttons' => [...]里每个按钮都要单独if ($model->can('...')) - 高频页面建议在控制器
beforeAction预查权限,用$auth->checkAccess($userId, $permission)批量查,避免反复调用can()查 DB 或缓存
最容易被忽略的点是:AccessControl 不处理 RBAC 权限粒度,它只认 @ 和 ?;细粒度控制(比如“作者只能删自己的文章”)必须靠 Rule 类 + can() + 后端逻辑三重兜底。漏掉任意一环,权限就是摆设。

















