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. c# 三种常见的委托

    参考  <编写高质量代码:改善C#程序的157个建议> , 尽量使用FCL中的委托声明. FCL: FrameWork Class Library 三种常用:Action.Func.Pre ...

  2. 2015最流行的Android组件、工具、框架大全

    Android 是目前最流行的移动操作系统之一. 随着新版本的不断发布, Android的功能也日益强大, 涌现了很多流行的应用程序, 也催生了一大批的优秀的组件. 本文试图将目前流行的组件收集起来以 ...

  3. Centos7安装PHP7

    安装依赖 yum updateyum install gcc-c++ libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel lib ...

  4. 进击的Python【第二十一章】

    s14day21 上节内容回顾: 1.请求周期 url> 路由 > 函数或类 > 返回字符串或者模板语言? Form表单提交: 提交 -> url > 函数或类中的方法 ...

  5. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...

  6. C++远征之封装篇(下)

    对象数组 类 x1[]; 栈中实例化,不用delete. 类 *X=new X[];//在堆中实例化,结尾需要用delete删除 delete []X; //这是数组的删除形式 X=NULL;

  7. CentOS利用nginx和php-fpm搭建owncloud私有云

    1.安装owncloud CentOS下有一键安装命令 yum install owncloud 默认配置目录: /etc/owncloud 默认内容目录: /usr/share/owncloud 2 ...

  8. Reactjs+Webpack+es2015 入门HelloWord(一)

    链接,自己很久前总结的blog. https://my.oschina.net/tangyuanyu/blog/730265

  9. smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed')解决办法

    raise SMTPAuthenticationError(code, resp) smtplib.SMTPAuthenticationError: (535, b'Error: authentica ...

  10. vs中使用beyondcompare比较

    开启 Visual Studio  的 [工具] /[选项] / [源代码管理] /[Visual Studio Team Foundation],并开启「配置用户工具」 如下图单击「添加」按钮 接着 ...