Yii rbac原理和实践
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原理和实践的更多相关文章
- Atitit 管理原理与实践attilax总结
Atitit 管理原理与实践attilax总结 1. 管理学分类1 2. 我要学的管理学科2 3. 管理学原理2 4. 管理心理学2 5. 现代管理理论与方法2 6. <领导科学与艺术4 7. ...
- Atitit.ide技术原理与实践attilax总结
Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...
- Atitit.异步编程技术原理与实践attilax总结
Atitit.异步编程技术原理与实践attilax总结 1. 俩种实现模式 类库方式,以及语言方式,java futuretask ,c# await1 2. 事件(中断)机制1 3. Await 模 ...
- Atitit.软件兼容性原理与实践 v5 qa2.docx
Atitit.软件兼容性原理与实践 v5 qa2.docx 1. Keyword2 2. 提升兼容性的原则2 2.1. What 与how 分离2 2.2. 老人老办法,新人新办法,只新增,少修改 ...
- Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法
Atitit 表达式原理 语法分析 原理与实践 解析java的dsl 递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...
- Atitit.gui api自动化调用技术原理与实践
Atitit.gui api自动化调用技术原理与实践 gui接口实现分类(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Sol ...
- Atitit.提升语言可读性原理与实践
Atitit.提升语言可读性原理与实践 表1-1 语言评价标准和影响它们的语言特性1 1.3.1.2 正交性2 1.3.2.2 对抽象的支持3 1.3.2.3 表达性3 .6 语言设计中的权 ...
- Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2
Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2 1. 数据采集1 1.1. http lib1 1.2. HTML Parsers,1 1.3. 第8章 web爬取199 1 2 ...
- Atitit.软件兼容性原理与实践 v3 q326.docx
Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api vs 修改旧的api1 3. Web方面的兼容性(js,html)1 3 ...
随机推荐
- BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3953 Solved: 1614[Submit][Stat ...
- BZOJ 3555: [Ctsc2014]企鹅QQ [字符串哈希]【学习笔记】
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 2046 Solved: 749[Submit][Statu ...
- float4数据类型
GPU是以四维向量为基本单位来计算的.4个浮点数所组成的float4向量是GPU内置的最基本类型.使用GPU对两个float4向量进行计算,与CPU对两个整数或两个浮点数进行计算一样简单,都是只需要一 ...
- Maven学习
http://www.cnblogs.com/sprinng/p/5141233.html 生成项目jar包失败 maven安装出现解决:http://blog.csdn.net/kjfcpua/ar ...
- Mysql5.5升级到5.7后MySQLdb不能正常使用的问题解决
ubuntu系统 报错信息1 Type "help", "copyright", "credits" or "license&qu ...
- 用js实现动画效果核心方式
为了做好导航菜单,有时候需要在菜单下拉的时候实现动画效果,所以这几天就研究了研究如何用js实现动画效果,实现动画核心要用到两个函数,一个是setTimeOut,另一个是setInterval. 下边我 ...
- .NET跨平台之旅:将示例站点升级至ASP.NET Core 1.0
北京时间6月28日凌晨,微软发布了 .NET Core 1.0,详见新闻 .NET Core 1.0 正式发布了 ,ASP.NET Core 1.0 也随之一起发布了. 紧跟这次发布,我们将跑在 Li ...
- SD卡的监听
摘要:在一般应用中,如果需要对占用空间比较大的文件操作,需要监听SD卡的状态,Android中对SD卡的监听状态操作步骤如下: 一.创建一个类继承于BroadcastReceiver public c ...
- .net core 源码解析-web app是如何启动并接收处理请求
最近.net core 1.1也发布了,蹒跚学步的小孩又长高了一些,园子里大家也都非常积极的在学习,闲来无事,扒拔源码,涨涨见识. 先来见识一下web站点是如何启动的,如何接受请求,.net core ...
- Xftp连接linux(ubuntu)时提示ssh服务器拒绝了密码,请再试一次
用xftp root连接时显示ssh服务器拒绝了密码,请重新连接.由于sshd的设置不允许root用户用密码远程登录,修改/etc/ssh/sshd_config文件,但必须是安装了openssh才会 ...