Yii2 RBAC配置过程


Yii2中有两种权限控制方式:一种是ACF,一种是RBAC。


ACF

ACF全称:Access Controller Filter,是一种比较简单的存取控制方式,针对登录已认证用户和未登录用户。 使用方式是在要加权限过滤的控制器的behaviors中写入access规则,如在PostController中:

RBAC

下面我们重点要讲的是RBAC,Role Base Access Controller。基于角色的权限控制过滤,结构如图:

实现过程:

第一步:建立授权数据:

1、配置授权组件:

注意 \ 的方向,不是 / 。

2、建立数据表:

在命令行下进入项目根目录,运行:

php ./yii migrate --migrationPath=@yii/rbac/migrations

生成rbac相关的4张表。

migrate前,migration表:

migrate后,migration表:

生成的4张表:

数据结构:

CREATE TABLE `auth_rule` (
  `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '规则名',
  `data` blob COMMENT '代码片段',
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT '权限规则表';

CREATE TABLE `auth_item` (
  `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '权限名',
  `type` smallint(6) NOT NULL COMMENT '类型,1:角色;2:操作',
  `description` text COLLATE utf8_unicode_ci COMMENT '描述备注',
  `rule_name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '规则名',
  `data` blob,
  `created_at` int(11) DEFAULT NULL,
  `updated_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`name`),
  KEY `rule_name` (`rule_name`),
  KEY `idx-auth_item-type` (`type`),
  CONSTRAINT `auth_item_ibfk_1` FOREIGN KEY (`rule_name`) REFERENCES `auth_rule` (`name`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT '权限记录表';

CREATE TABLE `auth_item_child` (
  `parent` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '父权限名',
  `child` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '子权限名',
  PRIMARY KEY (`parent`,`child`),
  KEY `child` (`child`),
  CONSTRAINT `auth_item_child_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `auth_item_child_ibfk_2` FOREIGN KEY (`child`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT '权限父子表';

CREATE TABLE `auth_assignment` (
  `item_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '权限记录名',
  `user_id` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '用户id',
  `created_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`item_name`,`user_id`),
  CONSTRAINT `auth_assignment_ibfk_1` FOREIGN KEY (`item_name`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT '用户授权表';

3、用authManager的API创建数据:

先看下表的关系:

再在console中创建控制器RbacController:

namespace console\controllers;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;
        
        // 添加 "createPost" 权限
        $createPost = $auth->createPermission('createPost');
        $createPost->description = '新增文章';
        $auth->add($createPost);
        
        // 添加 "updatePost" 权限
        $updatePost = $auth->createPermission('updatePost');
        $updatePost->description = '修改文章';
        $auth->add($updatePost);
        
        // 添加 "deletePost" 权限
        $deletePost = $auth->createPermission('deletePost');
        $deletePost->description = '删除文章';
        $auth->add($deletePost);
        
        // 添加 "approveComment" 权限
        $approveComment = $auth->createPermission('approveComment');
        $approveComment->description = '审核评论';
        $auth->add($approveComment);
        
        
        // 添加 "postadmin" 角色并赋予 "updatePost" “deletePost” “createPost”
        $postAdmin = $auth->createRole('postAdmin');
        $postAdmin->description = '文章管理员';
        $auth->add($postAdmin);
        $auth->addChild($postAdmin, $updatePost);
        $auth->addChild($postAdmin, $createPost);
        $auth->addChild($postAdmin, $deletePost);
        
        // 添加 "postOperator" 角色并赋予 “deletePost”
        $postOperator = $auth->createRole('postOperator');
        $postOperator->description = '文章操作员';
        $auth->add($postOperator);
        $auth->addChild($postOperator, $deletePost);
        
        // 添加 "commentAuditor" 角色并赋予 “approveComment”
        $commentAuditor = $auth->createRole('commentAuditor');
        $commentAuditor->description = '评论审核员';
        $auth->add($commentAuditor);
        $auth->addChild($commentAuditor, $approveComment);
        
        // 添加 "admin" 角色并赋予所有其他角色拥有的权限
        $admin = $auth->createRole('admin');
        $admin->description = '系统管理员';
        $auth->add($admin);
        $auth->addChild($admin, $postAdmin);
        $auth->addChild($admin, $commentAuditor);
        
        
        // 为用户指派角色。其中 1 和 2 是由 IdentityInterface::getId() 返回的id (译者注:user表的id)
        // 通常在你的 User 模型中实现这个函数。
        $auth->assign($admin, 1);
        $auth->assign($postAdmin, 2);
        $auth->assign($postOperator, 3);
        $auth->assign($commentAuditor, 4);
    }
} 

然后在命令行中运行:

php ./yii rbac/init

再去看一下数据表,就会发现数据已经写入了。如:

第二步:执行权限检查:

在需要检查权限的操作中,加入权限检查代码:

注意看一下上面有没有这句:use yii\web\ForbiddenHttpException;

接下来,你就可以换不同的账号测试一下能不能操作该动作了。

RBAC实现

参见下面:

https://lulublog.cn/ps/hsYiP2

http://www.manks.top/yii2_frame_rbac_template.html

这两个装载可以对照看下:

https://www.jianshu.com/p/d2fc8c55dadb

http://t.zoukankan.com/grimm-p-5706112.html






参考资料

Yii 2.0 权威指南 安全(Security): 授权(Authorization) https://www.yiichina.com/doc/guide/2.0/security-authorization


返回