Yii框架中集成分层的 RBAC,代码位于vendor\yiisoft\yii2\rbac中,rbac工作原理分为两部分,建立授权数据和进行权限检查。

  如上,一个角色拥有某个权限,如果希望用户拥有这个权限,那么就将拥有该权限的角色赋予给用户,特别是当系统中用户数量非常大的时候,如果需要修改权限只需要修改角色就可以了。

  角色和权限都可以按层次组织。特定情况下,一个角色可能由其他角色或权限构成, 而权限又由其他的权限构成。 一个角色可以包含一个权限,反之则不行。

  特定的权限,可以用一个规则 rule 与一个角色或者权限关联。一个规则用一段代码代表, 规则的执行是在检查一个用户是否满足这个角色或者权限时进行的。例如,"改帖" 的权限 可以使用一个检查该用户是否是帖子的创建者的规则。权限检查中,如果该用户 不是帖子创建者,那么他(她)将被认为不具有 "改帖"的权限。

  Yii中rbac的角色权限数据可以通过文件和数据库进行存放,如果是数据库存放角色权限数据,那么需要配置config目录下web.php和console.php中的authManager。下面以建立一个可以进行注册登录发帖的并且用户只可以修改自己文章的系统为例。

第一步:基本配置

              web.php

            console.php

第二步:初始化数据库

命令行中运行yii的migrate命令,需要将yii.bat所在目录添加到系统环境变量中就可以像下面这样执行了。

  

然后会在数据库中多出四个表,auth_item, auth_rule, auth_item_child, auth_assignment。

                auth_item表

存放权限数据,包含各个权限的名字和描述以及关联的规则,具体的字段含义可以参考yii\rbac\Item类:

<?php
namespace yii\rbac; use yii\base\Object; /**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Item extends Object
{
const TYPE_ROLE = 1;
const TYPE_PERMISSION = 2; /**
* @var integer the type of the item. This should be either [[TYPE_ROLE]] or [[TYPE_PERMISSION]].
*/
public $type;
/**
* @var string the name of the item. This must be globally unique.
*/
public $name;
/**
* @var string the item description
*/
public $description;
/**
* @var string name of the rule associated with this item
*/
public $ruleName;
/**
* @var mixed the additional data associated with this item
*/
public $data;
/**
* @var integer UNIX timestamp representing the item creation time
*/
public $createdAt;
/**
* @var integer UNIX timestamp representing the item updating time
*/
public $updatedAt;
}

item中的type类型,表示该权限是包含一个权限集合的角色TYPE_ROLE ,还是单独权限TYPE_PERMISSION。auth_item_child就储存了角色和权限的父子关系数据。

  auth_rule表中定义了规则,auth_item_child储存了用户和角色的关系数据。

第三部:创建角色和权限

  这里创建基本的角色author和editArticle权限,以及一个规则,规定只有对自己的文章可以有editArticle权限。在@app目录下新建rbac文件夹:

<?php
namespace app\rbac; use yii\rbac\Rule; /**
* Created by PhpStorm.
* User: mao
* Date: 2016/10/28
* Time: 0:22
*/
class AuthorRule extends Rule
{
public $name = 'isAuthor'; public function execute($user, $item, $params)
{
return isset($params['post']) ? $params['post'] -> authorId == $user : false;
}
}

  该规则根据传入的$param数据判断,要修改的文章作者是否是自己。下面进行角色和权限的初始化,新建rbacController控制器,

<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\rbac\AuthorRule; class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app -> authManager; $rule = new AuthorRule();
$auth -> add($rule); $updateArticle = $auth -> createPermission('updateArticle');
$updateArticle -> description = '更新自己文章';
$updateArticle -> ruleName = $rule -> name;
$auth -> add($updateArticle); $author = $auth -> createRole('author');
$auth -> add($author);
$auth -> addChild($author, $updateArticle);
}
}

  访问,http://localhost/?r=rbac/init,后数据库中会生产相应的权限角色数据。

其中,rule中data是被序列化后的对象。

反序列化后如下,

保存了rule的基本信息,权限创建好了,需要给每一个注册的用户赋予author权限,具体的注册和发表文章可以自己实现,下面贴一下注册时授予权限的代码:

    public function actionRegister()
{
$member = new Member(['scenario' => 'register']);
$post = Yii::$app -> request -> post();
if(isset($post['Member']))
{
$exist = Member::findIdentityByUsername($post['Member']['username']);
if(!$exist && $member -> load($post) && $member -> setPassword() && $member -> save())
{
$auth = Yii::$app -> authManager;
$author = $auth -> getRole('author');
$auth -> assign($author, $member -> id);
Yii::$app -> user -> login($member);
return $this -> goHome();
}
} return $this -> render("register", ['model' => $member]);
}

用户注册后通过getRole获得角色,然后赋予给用户。下面就是当用户修改文章的时候,根据角色和权限进行判断是否有权限修改。可以通过yii::$app -> user的can方法来进行验证。

    public function actionEdit()
{
$articleId = Yii::$app -> request -> get("id");
$article = Article::findOne(['id' => $articleId]);
if($article){
//鉴定是否拥有updateArticle权限
if(Yii::$app -> user -> can('updateArticle', ['post' => $article])){
return $this -> render('edit', ['article' => $article]);
}
return $this -> render('noAuth');
}else{
return $this -> redirect('/?r=article/articles');
}
}

其中,第二个参数就是以后会传给AuthorRule中的execute方法的最后一个参数,这里传入的是article的ActiveRecord对象。

当我们对别人的文章点击编辑后会跳转到你没有权限的提示页面,而自己的文章可以正常修改。

提示没有权限。

参考:

http://www.yiichina.com/doc/guide/2.0/security-authorization

http://en.wikipedia.org/wiki/Role-based_access_control

Yii rbac原理和实践的更多相关文章

  1. Atitit 管理原理与实践attilax总结

    Atitit 管理原理与实践attilax总结 1. 管理学分类1 2. 我要学的管理学科2 3. 管理学原理2 4. 管理心理学2 5. 现代管理理论与方法2 6. <领导科学与艺术4 7. ...

  2. Atitit.ide技术原理与实践attilax总结

    Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...

  3. Atitit.异步编程技术原理与实践attilax总结

    Atitit.异步编程技术原理与实践attilax总结 1. 俩种实现模式 类库方式,以及语言方式,java futuretask ,c# await1 2. 事件(中断)机制1 3. Await 模 ...

  4. Atitit.软件兼容性原理与实践 v5 qa2.docx

    Atitit.软件兼容性原理与实践   v5 qa2.docx 1. Keyword2 2. 提升兼容性的原则2 2.1. What 与how 分离2 2.2. 老人老办法,新人新办法,只新增,少修改 ...

  5. Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法

    Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...

  6. Atitit.gui api自动化调用技术原理与实践

    Atitit.gui api自动化调用技术原理与实践 gui接口实现分类(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Sol ...

  7. Atitit.提升语言可读性原理与实践

    Atitit.提升语言可读性原理与实践 表1-1  语言评价标准和影响它们的语言特性1 1.3.1.2  正交性2 1.3.2.2  对抽象的支持3 1.3.2.3  表达性3 .6  语言设计中的权 ...

  8. Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2

    Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2 1. 数据采集1 1.1. http lib1 1.2. HTML Parsers,1 1.3. 第8章 web爬取199 1 2 ...

  9. Atitit.软件兼容性原理与实践 v3 q326.docx

    Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api  vs  修改旧的api1 3. Web方面的兼容性(js,html)1 3 ...

随机推荐

  1. MPLS与LDP从入门到了解

    多协议标签交换(MPLS)是一种用于快速转发数据包的技术,它的出现就是为了提高转发效率.因为IP转发大多靠软件进行,在转发的每一跳都要进行至少一次最长匹配查找,操作复杂导致转发速度比较慢.有些厂商借鉴 ...

  2. Spring.net 配置说明

    Spring.net使用说明   使用方法: 1.在配置文件设置Spring.net 节点  在配置节中,声明Spring.net,配置 context,objects 标签,来源(type) < ...

  3. 启用SQLite的Data Provider 运行WECOMPANYSITE时遇到ERROR CREATING CONTEXT 'SPRING.ROOT': ERROR THROWN BY A DEPENDENCY OF OBJECT 'SYSTEM.DATA.SQLITE'

    从网上下载的源码WeCompanySite,运行时报错 Error creating context 'spring.root': Error thrown by a dependency of ob ...

  4. mac机上搭建php56/nginx 1.8.x/thinkphp 3.2.x/gearman扩展/seaslog扩展/redis扩展环境

    php的各种扩展配置起来实在不容易,记录一下备忘: 一.php56 安装 虽然php7出来了,但是没用过,不知道有没有坑,这里仍然使用php5.6版本 1.1 安装php/php-pfm brew u ...

  5. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  6. [LeetCode] Combination Sum II 组合之和之二

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...

  7. CSS3常用属性(边框、背景、文本效果、2D转换、3D转换、过渡、有过渡效果大图轮播、动画)

    CSS3边框: 1.CSS3圆角:border-radius  属性--创建边框线的圆角 <body style="font-size:24px; color:#60F;"& ...

  8. js整理

    Js脚本语音 网页里面使用的脚本语音 基础语法 注释语法  单行注释// 多行注释/**/ 嵌入js代码  尽量靠下写  用<script type="text/javascript& ...

  9. Ajax在静态页面中向指定url发送json请求获取返回的json数据

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  10. ubuntu16.04配置py-faster-rcnn

    在ubuntu16.04下编译安装了py-faster-rcnn. 主要步骤包括:安装cuda/cudnn,换apt源,装开源显卡驱动,装caffe依赖的apt包和python包,下载py-faste ...