YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例


Posted in PHP onMarch 18, 2020

本文实例讲述了YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用。分享给大家供大家参考,具体如下:

在使用YII2中自带的RBAC时,需要先配置config/web.php:

return [
  // ...
  'components' => [
    'authManager' => [
      'class' => 'yii\rbac\DbManager',
    ],
    // ...
  ],
];

如果你需要运行yii migrate来创建表,那么config/console.php也需要同上面一样配置一下。

cmd进入项目目录,运行如下命令:

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

你会发现在数据库中创建了四张表

auth_assignment 角色与用户的关联表
auth_item 存放角色与权限,通过type字段区分
auth_item_child 存放角色与权限的上下级关系
auth_rule 规则表,用于扩展权限功能

为了演示,我们在控制器下分别写四个方法,分别用来创建权限,创建角色,指派角色,使用规则。

IndexController.php代码如下:

<?php

namespace app\controllers;

use YII;
use app\models\MyUserLogin;
use app\rbac\UserUpdSelfRule;
use app\controllers\BaseController;

class IndexController extends BaseController
{

  //首页
  public function actionIndex()
  {
    $this->renderPartial('index');
  }

  //登陆
  public function actionLogin()
  {
    if (YII::$app->request->isPost) {
      $user = new MyUserLogin();
      $user->load(YII::$app->request->post(), '');

      if ($user->login()) {
        echo '登陆成功';
      } else {
        echo '登陆失败';
      }

    } else {
      return $this->renderPartial('login');
    }
  }

  //为了演示,这里我们添加几条权限
  public function actionPer()
  {
    $auth = YII::$app->authManager;
    //创建用户删除权限
    $per = $auth->createPermission('user/del');
    $per->description = '删除用户';
    $auth->add($per);
    //创建用户更新权限
    $per = $auth->createPermission('user/upd');
    $per->description = '更新用户';
    $auth->add($per);
    //创建用户添加权限
    $per = $auth->createPermission('user/add');
    $per->description = '添加用户';
    $auth->add($per);
    //创建用户查看权限
    $per = $auth->createPermission('user/list');
    $per->description = '查看用户列表';
    $auth->add($per);
  }

  //添加角色
  public function actionRole()
  {
    $auth = YII::$app->authManager;

    //添加管理员角色
    $admin = $auth->createRole('admin');
    $admin->description = '管理员';
    $auth->add($admin);
    //给管理员赋予权限
    $auth->addChild($admin, $auth->getPermission('user/del'));
    $auth->addChild($admin, $auth->getPermission('user/upd'));
    $auth->addChild($admin, $auth->getPermission('user/add'));
    $auth->addChild($admin, $auth->getPermission('user/list'));

    //添加普通员工角色
    $employee = $auth->createRole('employee');
    $employee->description = '普通员工';
    $auth->add($employee);
    $auth->addChild($employee, $auth->getPermission('user/list'));
    $auth->addChild($employee, $auth->getPermission('user/add'));
  }

  //给用户指派角色
  public function actionAssign()
  {
    $auth = YII::$app->authManager;

    //注意这里的2是用户的ID,即你用户表user里的ID
    //也可通过YII::$app->user->id获取
    $auth->assign($auth->getRole('admin'), 1);

    $auth->assign($auth->getRole('employee'), 2);
  }

  //添加规则
  public function actionRule()
  {
    $auth = YII::$app->authManager;
    $rule = new UserUpdSelfRule();
    $auth->add($rule);

    //创建权限,与规则关联
    $per = $auth->createPermission('user/upd/updSelf');
    $per->description = '用户只能修改自已';
    $per->ruleName = $rule->name;
    $auth->add($per);

    //这里,要注意,要把user/upd/updSelf权限设为user/upd的父级
    //要不然,普通员工访问user/upd这个方法会被拦住
    $auth->addChild($per, $auth->getPermission('user/upd'));
    //给普通员工赋予user/upd/updSelf权限,注意我们这里并没有给员工赋予user/upd权限
    $auth->addChild($auth->getRole('employee'), $per);
  }
}

我们在项目目录下创建rbac目录,并创建UserUpdSelfRule.php,来实现用户只能修改自已信息的规则。

<?php

//注意命名空间要跟你的目录对应
namespace app\rbac;

use yii\rbac\Rule;

//必须继承自yii\rbac\Rule
class UserUpdSelfRule extends Rule
{
  public $name = 'userUpdSelf';

  //必须要实现execute方法
  //$user表示用户ID
  //$item规则相关的角色或者权限
  //$params传递过来的参数
  public function execute($user, $item, $params)
  {
    //如果没有设置参数ID,直接返回true
    if (!isset($params['id'])) {
      return true;
    }
    //判断id是否是当前用户ID
    return ($params['id'] == $user) ? true : false;
  }
}

我们访问index/per查看数据表中的变化。

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/role结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/assign结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/rule结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

为了能够对我们的模块,控制器,方法进行权限控制,我们需要创建一个基类来统一处理,上面的控制器就是继承自基类。

BaseController.php代码如下:

<?php

namespace app\controllers;

use YII;
use yii\web\Controller;

class BaseController extends Controller
{
  //不需要验证的
  protected $noCheckAccess = [
    'index/index',
    'index/per',
    'index/role',
    'index/assign',
    'index/rule',
    'index/login',
  ];

  //不需要登陆的
  protected $noLogin = [
    'index/login',
  ];

  //验证权限
  //注意,不要把获取模块名,控制器名,方法名写到init()函数里,那样是获取不到的
  //这个坑我已经踩了,大家就不用再去踩了
  public function beforeAction($action)
  {
    $mid = !empty($this->module->id) ? $this->module->id : '';
    $cid = !empty($this->id) ? $this->id : '';
    $aid = !empty($action->id) ? $action->id : '';

    //如果模块为basic,我们只验证控制器/方法
    if ($mid == 'basic') {
      $per = "{$cid}/{$aid}";
    } else {
      $per = "{$mid}/{$cid}/{$aid}";
    }

    if (!in_array($per, $this->noLogin)) {
      if (!$this->checkOnline()) {
        $this->redirect('index/login');
      }
    }

    if (!in_array($per, $this->noCheckAccess)) {
      if (!YII::$app->user->can($per)) {
        die('你没有权限');
      }
    }

    return parent::beforeAction($action);
  }

  //检查是否在线
  public function checkOnline()
  {
    return !empty(YII::$app->user->id) ? true : false;
  }
}

为了演示,我们创建一个UserController.php,代码如下:

<?php

namespace app\controllers;

use YII;
use app\controllers\BaseController;

class UserController extends BaseController
{
  public function actionUpd()
  {
    $id = YII::$app->request->get('id', 0);

    echo 'user id : ', YII::$app->user->id, '<br>';

    //先判断用户有没有只能修改自已的权限
    if (YII::$app->user->can('user/upd/updSelf')) {
      //然后再判断修改ID是否与自已的ID一样,在UserUpdSelfRule里进行判断
      if (YII::$app->user->can('user/upd/updSelf', ['id' => $id])) {
        echo '有权修改自已';
      } else {
        echo '不能修改除自已以外的';
      }
    } else {
      echo '修改所有';
    }
  }

  public function actionDel()
  {
    echo 'user id : ', YII::$app->user->id, '<br>';
    echo 'user del';
  }

  public function actionList()
  {
    echo 'user id : ', YII::$app->user->id, '<br>';
    echo 'user list';
  }

  public function actionAdd()
  {
    echo 'user id : ', YII::$app->user->id, '<br>';
    echo 'user add';
  }
}

我的用户表里有两个用户

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

分别登陆这两个用户,然后让他们访问user/add,user/del,user/list,user/upd,结果如下:

admin用户状态如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

test用户状态如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

test之所以能够访问user/upd是因为我们把user/upd/updSelf设为了user/upd的父级,如果没有设置,这里是会被拦住的。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
php代码优化及php相关问题总结
Oct 09 PHP
PHP parse_url 一个好用的函数
Oct 03 PHP
PHP表单提交表单名称含有点号(.)则会被转化为下划线(_)
Dec 14 PHP
PHP图片验证码制作实现分享(全)
May 10 PHP
奉献出一个封装的curl函数 便于调用(抓数据专用)
Jul 22 PHP
php异常处理使用示例
Feb 25 PHP
2014最热门的24个php类库汇总
Dec 18 PHP
PHP静态成员变量
Feb 14 PHP
PHP中include和require的区别实例分析
May 07 PHP
PHPExcel实现表格导出功能示例【带有多个工作sheet】
Jun 13 PHP
PHP安装BCMath扩展的方法
Feb 13 PHP
laravel框架实现去掉URL中index.php的方法
Oct 12 PHP
Laravel框架下的Contracts契约详解
Mar 17 #PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
Mar 16 #PHP
PHP代码加密的方法总结
Mar 13 #PHP
YII2框架中behavior行为的理解与使用方法示例
Mar 13 #PHP
YII2框架中actions的作用与使用方法示例
Mar 13 #PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 #PHP
TP5框架安全机制实例分析
Apr 05 #PHP
You might like
destoon利用Rewrite规则设置网站安全
2014/06/21 PHP
php实现的Curl封装类Curl.class.php用法实例分析
2015/09/25 PHP
微信支付扫码支付php版
2016/07/22 PHP
jquery offset函数应用实例
2012/11/14 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
原生Js实现简易烟花爆炸效果的方法
2015/03/20 Javascript
纯jquery实现模仿淘宝购物车结算
2015/08/20 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
vue 使用html2canvas将DOM转化为图片的方法
2018/09/11 Javascript
layer更改皮肤的实现方法
2019/09/11 Javascript
[10:49]2014国际邀请赛 叨叨刀塔第二期为真正的电竞喝彩
2014/07/21 DOTA
python实现排序算法
2014/02/14 Python
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
Python标准库之collections包的使用教程
2017/04/27 Python
解决pycharm界面不能显示中文的问题
2018/05/23 Python
numpy数组广播的机制
2019/07/12 Python
通过python连接Linux命令行代码实例
2020/02/18 Python
学会python自动收发邮件 代替你问候女友
2020/05/20 Python
jupyter notebook远程访问不了的问题解决方法
2021/01/11 Python
Turnbull & Asser官网:英国皇室御用的顶级定制衬衫
2019/01/31 全球购物
机械设计制造专业个人求职信
2013/09/25 职场文书
酒吧副总经理岗位职责
2013/12/10 职场文书
简历自我评价怎么写好呢?
2014/01/04 职场文书
高中数学教学反思
2014/01/30 职场文书
审计专业自荐信范文
2014/04/21 职场文书
村抢险救灾方案
2014/05/09 职场文书
小学生环保倡议书
2014/05/15 职场文书
驾驶员安全责任书
2014/07/22 职场文书
《中国梦我的梦》大学生演讲稿
2014/08/20 职场文书
四风查摆问题自查报告
2014/10/10 职场文书
学习走群众路线心得体会
2014/11/05 职场文书
如何把新闻人物写得立体、鲜活?
2019/08/14 职场文书
Filebeat 采集 Nginx 日志的方法
2021/03/31 Servers
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android
基于Android10渲染Surface的创建过程
2022/08/14 Java/Android