资讯专栏INFORMATION COLUMN

yii实现rbac详解

lentrue / 763人阅读

摘要:在中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

之前有个朋友问我yii的rbac怎么做,以前大学的时候有接触过,很长时间没用了,也忘记了,正好这几天比较闲,重新捋了下大体思路,希望可以帮到困在yii的rbac上的门外han~~

RBAC~~什么是RBAC

基于角色的权限访问控制(Role-Based Access
Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。

RBAC~~权限认证流程

用户登录后认证用户的角色

根据角色 查询出该角色拥有的权限操作列表

访问某一个权限(操作)时判断该用户是否拥有访问的能力

yii如何实现呢??这里我们采用数据库的方式实现,会相对来说比较安全

RBAC~~权限数据生成

首先在web/console.php中配置组件

"authManager" => [
    "class" => "yii
bacDbManager",
    // auth_item (role permission)
    // auth_item_child (role->permission)
    // auth_assignment (user->role)
    // auth_rule (rule)
    "itemTable" => "{{%auth_item}}",
    "itemChildTable" => "{{%auth_item_child}}",
    "assignmentTable" => "{{%auth_assignment}}",
    "ruleTable" => "{{%auth_rule}}",
],

接着使用yii脚本,生成数据表

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

然后我们需要读取所有的控制器与方法 存储到权限表,方便判断的时候 读取数据库 进而进行判断

public function actionInit()
{
    $trans = Yii::$app->db->beginTransaction();
    try {
        //构建控制器目录
        $dir = dirname(dirname(__FILE__)). "/modules/controllers";
        //找到控制器目录下的所有文件
        $controllers = glob($dir. "/*");
        $permissions = [];
        foreach ($controllers as $controller) {
            $content = file_get_contents($controller);
            //找到Controller即可
            preg_match("/class ([a-zA-Z]+)Controller/", $content, $match);
            $cName = $match[1];
            $permissions[] = strtolower($cName. "/*");
            //正则匹配文本中的所以action
            preg_match_all("/public function action([a-zA-Z_]+)/", $content, $matches);
            foreach ($matches[1] as $aName) {
                $permissions[] = strtolower($cName. "/". $aName);
            }
        }
        $auth = Yii::$app->authManager;

        //为什么$auth可以操作到该表
        foreach ($permissions as $permission) {
            //是否存在该权限
            if (!$auth->getPermission($permission)) {
                $obj = $auth->createPermission($permission);
                $obj->description = $permission;
                $auth->add($obj);
            }
        }
        $trans->commit();
        echo "import success 
";
    } catch(Exception $e) {
        $trans->rollback();
        echo "import failed 
";
    }
}

接着yii下 就可以生成权限数据了

./yii rbac/init

然后,看看数据库

RBAC~~权限访问控制

过滤器的使用原理:

权限的控制实则就是判断当前的用户是否拥有对方法,控制器访问的权限 在这之前需要使用过滤器 对用户的登录与未登录进行认证过滤 ,所有的控制器 extends CommonController,在访问子类控制器的时候,会自动去访问behaviors方法,在子控制器中,通过重写父类的属性指定允许访问的方法,进而实现过滤的作用。

 //子类可以通过重写该属性 实现认证
 public $mustlogin = ["createrule", "createrole", "roles", "assignitem"];
 //行为过滤器
 public function behaviors()
    {
        return [
            "access" => [
                "class" => yiifiltersAccessControl::className(),
                "user" => "admin",
                "only" => $this->actions,
                "except" => $this->except,
                "rules" => [
                    [
                        "allow" => false,
                        "actions" => empty($this->mustlogin) ? [] : $this->mustlogin,
                        "roles" => ["?"],
                    ],
                    [
                        "allow" => true,
                        "actions" => empty($this->mustlogin) ? [] : $this->mustlogin,
                        "roles" => ["@"],
                    ],
                ],
            ],
        ];
    }

//那么如何实现访问 判断用户是否拥有权限呢??yii提供了beforeAction,在CommonController进行判断

     /*权限访问判断*/
    public function beforeAction($action)
    {
         //调用父类方法   防止被重写掉
        if (!parent::beforeAction($action)) {
            return false;
        }
        //获取到当前的控制器
        $controller = $action->controller->id;
        $actionName = $action->id;
        if (Yii::$app->admin->can($controller. "/*")) {
            return true;
        }
        if (Yii::$app->admin->can($controller. "/". $actionName)) {
            return true;
        }
        throw new yiiwebUnauthorizedHttpException("对不起,您没有访问". $controller. "/". $actionName. "的权限");
        // return true;
    }

//这样即可实现权限的访问控制   

到这里,我们就是实现了权限的访问判断,接下来 我们还要实现 不同用户显示不同的菜单,如何实现呢??

原理:
将菜单栏以数组的形式进行存储,通过循环数组,判断当前用户访问的控制器是否拥有对应的权限

 controller->id;
                $action = Yii::$app->controller->action->id;
                //循环菜单
                foreach (Yii::$app->params["adminmenu"] as $menu) {
                    $show = "hidden";
                    if (Yii::$app->admin->can($menu["module"]. "/*")) {
                        $show = "show";
                    } else {
                        if (empty($menu["submenu"]) && !Yii::$app->admin->can($menu["url"])) {
                            continue;
                        } else {
                            foreach ($menu["submenu"] as $sub) {
                               //判断当前的用户是否拥有访问该控制器的权限
                                if (Yii::$app->admin->can($menu["module"]. "/". $sub["url"])) {
                                    $show = "show";
                                }
                            }
                        }
                    }
                ?>
              
  • "> href=""> ">
  • 这样就实现了不同登录用户 不同菜单的展示

    RBAC~~创建不同角色

    原理:
    不同角色拥有不同权限,超级管理员可以创建用户,及分配权限给不同用户,首先我们得有个用户->

     /*角色添加*/
        public function actionCreaterole()
        {
            if (Yii::$app->request->isPost) {
                //DBmanager对象
                $auth = Yii::$app->authManager;
                //创建一个role的对象
                $role = $auth->createRole(null);
                $post = Yii::$app->request->post();
                if (empty($post["name"]) || empty($post["description"])) {
                    throw new Exception("参数错误");
                }
                $role->name = $post["name"];
                $role->description = $post["description"];
                $role->ruleName = empty($post["rule_name"]) ? null : $post["rule_name"];
                $role->data = empty($post["data"]) ? null : $post["data"];
                if ($auth->add($role)) {
                    Yii::$app->session->setFlash("info", "添加成功");
                }
            }
            return $this->render("_createitem");
        }
    

    原理:
    所谓的分配权限就是将给用户分配是否可以访问控制器的权限,确认要分配的对象 实则是指定表的user_id对应的item_name值

    具体如何做呢?? 看这里->

     /* 分配权限 */
        public function actionAssignitem($name)
        {
            //获取到角色
            $name = htmlspecialchars($name);
            $auth = Yii::$app->authManager;
            //获取到当前角色的信息
            $parent = $auth->getRole($name);
            if (Yii::$app->request->isPost) {
                $post = Yii::$app->request->post();
                if (Rbac::addChild($post["children"], $name)) {
                    Yii::$app->session->setFlash("info", "分配成功");
                }
            }
            $children = Rbac::getChildrenByName($name);
            //获取当前用户的
            $roles = Rbac::getOptions($auth->getRoles(),$parent);
            //获取当前用户拥有的权限
            $permissions = Rbac::getOptions($auth->getPermissions(), $parent);
            return $this->render("_assignitem", ["parent" => $name, "roles" => $roles, "permissions" => $permissions, "children" => $children]);
        }
    
    RBAC~~规则指定,更高级的权限指定

    接下来,不得不谈谈rbac的规则,这又是个什么东西呢?? 所谓的规则 其实就是对用户的权限的额外限制
    原理:
    通过定义规则类,添加用户的时候指定规则名称 就可以实现对用户的权限的额外限制,
    数据表中,data字段就是实例化的自定义规则类对象

    比如我们定义这样一个自定义规则类

    /*实现分类只能由添加者删除*/
    class AuthorRule extends Rule
    {
        public $name = "isAuthor";
        //当前的用户,权限,额外的参数
        public function execute($user, $item, $params)
        {
            $action = Yii::$app->controller->action->id;
            //对delete方法 进行额外限制
            if ($action == "delete") {
                //获取到当前分类是由那个用户添加的  不允许其他用户删除
                $cateid = Yii::$app->request->get("id");
                $cate = Category::findOne($cateid);
                return $cate->adminid == $user;
            }
            return true;
        }
    }

    我们如何创建这个规则到数据表中呢??

    /*创建规则*/
        public function actionCreaterule()
        {
            if (Yii::$app->request->isPost) {
                $post = Yii::$app->request->post();
                if (empty($post["class_name"])) {
                    throw new Exception("参数错误");
                }
                //指定当前的规则命名空间
                $className = "appmodels". $post["class_name"];
                if (!class_exists($className)) {
                    throw new Exception("规则类不存在");
                }
                $rule = new $className;
                //使用authManager组件将当前的规则类 保存到数据库
                if (Yii::$app->authManager->add($rule)) {
                    Yii::$app->session->setFlash("info", "添加成功");
                }
            }
            return $this->render("_createrule");
        }
        

    这样再添加用户的时候,就可以指定规则,进而实现对更加高级的指定权限

    到这里,基本完成了用户创建,权限分配,及规则指定,希望可以帮到大家~~

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/23117.html

    相关文章

    • Yii2 restful接口方式开发,权限控制(yii2-rest-rbac)

      摘要:根据修改,只是方式,这个相当于的版本。适合用于前后端分离项目,方式提供接口,实现对接口的权限控制。 根据yii2-admin(https://github.com/mdmsoft/yi...)修改,yii2-admin只是web方式,这个相当于yii2-admin的rest版本。适合用于前后端分离项目,rest方式提供接口,实现对接口的权限控制。项目地址:https://github....

      whataa 评论0 收藏0
    • Yii授权之基于角色的存取控制 (RBAC

      摘要:一基本概念角色是权限的集合例如建贴改贴。特定情况下,一个角色可能由其他角色或权限构成,而权限又由其他的权限构成。提供了两套授权管理器和。前者使用脚本存放授权数据,而后者使用数据库存放授权数据。该表存放授权条目的层次关系。 一:基本概念 角色是 权限 的集合 (例如:建贴、改贴)。一个角色 可以指派给一个或者多个用户。要检查某用户是否有一个特定的权限, 系统会检查该包含该权限的角色是否指...

      greatwhole 评论0 收藏0
    • yii2搭建完美后台并实现rbac权限控制实例教程

      摘要:利用渲染后台模板后台的模板我们采用利用插播一曲是一个完全响应管理模板。基于框架,易定制模板。适合多种屏幕分辨率,从小型移动设备到大型台式机。内置了多个页面,包括仪表盘邮箱日历锁屏登录及注册错误错误等页面。 作者:白狼 出处:http://www.manks.top/yii2_fra... 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保...

      neu 评论0 收藏0
    • Yii2的RBAC实现

      摘要:一的前期准备的权限管理需要知道怎么给用户分配角色,给角色分配权限,以权限来精细化需要的操作,判断是否有权限来操作这一步,达到管理权限的目的。若没有则渲染不显示数据提交更新相应的修改或者增加。 一、RBAC的前期准备 RBAC的权限管理需要知道怎么给用户分配角色,给角色分配权限,以权限来精细化需要的操作,判断是否有权限来操作这一步,达到管理权限的目的。 先展示下要达到的效果 : show...

      xiaoxiaozi 评论0 收藏0
    • Yii-Casbin:在 Yii 里使用 Casbin,支持 ACL、RBAC多种模型的权限管理框架

      摘要:是一个用语言打造的轻量级开源访问控制框架,目前在开源。采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制基于属性的访问控制等。 PHP-Casbin 是一个用 PHP 语言打造的轻量级开源访问控制框架( https://github.com/php-casbin... ),目前在 GitHub 开源。PHP-Casbin 采用了元模型的设计思想,支持多种经典的访问...

      shusen 评论0 收藏0

    发表评论

    0条评论

    lentrue

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <