【Yii2】Yii2使用yii2-admin做RBAC权限管理的安装基本使用

RBAC 基于角色的权限管理

为什么要管理权限

在我们的系统中,存在不同的角色,每个角色对应的操作各不相同。

比如一个角色负责发布文章,他的上级角色负责审核文章,另一个上级则发布文章和审核文章的权限都有。

这时候就需要一个标准化的工作流来处理这些逻辑。

为什么是RBAC

像这种需求,在大部分管理系统都是存在的,经过一段时间的抽象化,大家便总结出了RBAC权限管理.

基本的逻辑

  • 一个用户包含多个角色
  • 一个角色包含多个操作
  • 每个角色的操作允许相互重复

这样就可以解决复杂业务逻辑下的权限分配问题。

为什么是yii2-admin

其实这部分的模块是可以自己写的,因为RBAC权限管理在Yii2的框架内作为基础库已经存在了。

而用yii2-admin的原因在于,不重复造轮子,或者说,不重复造不是很重要的轮子~

安装

项目地址

推荐使用谷歌,第一个就是项目的github地址

https://github.com/mdmsoft/yii2-admin

安装方式

第一种采用composer安装

php composer.phar require mdmsoft/yii2-admin “~2.0”

第二种是直接下载源代码,再通过别名的方式引入,为了方便直接修改代码,我这里采用直接引入的方式。

config/web

'aliases' => [
        '@mdm/admin' => '@app/components/yii2-admin',
    ],    
'modules' => [
'admin' => [
            'class' => 'mdm\admin\Module',
            'layout' => 'left-menu',
            ],
    ],

创建对应数据表

这个数据表是Yii自带的,文件位置为 vendor/yiisoft/yii2/rbac/migrations/schma-mysql.sql

/**
 * Database schema required by \yii\rbac\DbManager.
 *
 * @author Qiang Xue <[email protected]>
 * @author Alexander Kochetov <[email protected]>
 * @link http://www.yiiframework.com/
 * @copyright 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @since 2.0
 */

drop table if exists `auth_assignment`;
drop table if exists `auth_item_child`;
drop table if exists `auth_item`;
drop table if exists `auth_rule`;

create table `auth_rule`
(
   `name`                 varchar(64) not null,
   `data`                 blob,
   `created_at`           integer,
   `updated_at`           integer,
    primary key (`name`)
) engine InnoDB;

create table `auth_item`
(
   `name`                 varchar(64) not null,
   `type`                 smallint not null,
   `description`          text,
   `rule_name`            varchar(64),
   `data`                 blob,
   `created_at`           integer,
   `updated_at`           integer,
   primary key (`name`),
   foreign key (`rule_name`) references `auth_rule` (`name`) on delete set null on update cascade,
   key `type` (`type`)
) engine InnoDB;

create table `auth_item_child`
(
   `parent`               varchar(64) not null,
   `child`                varchar(64) not null,
   primary key (`parent`, `child`),
   foreign key (`parent`) references `auth_item` (`name`) on delete cascade on update cascade,
   foreign key (`child`) references `auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

create table `auth_assignment`
(
   `item_name`            varchar(64) not null,
   `user_id`              varchar(64) not null,
   `created_at`           integer,
   primary key (`item_name`, `user_id`),
   foreign key (`item_name`) references `auth_item` (`name`) on delete cascade on update cascade,
   key `auth_assignment_user_id_idx` (`user_id`)
) engine InnoDB;

使用

接下来访问 http://localhost/admin/

这里写图片描述

这里我们可以看到

  • 分配角色
  • 角色列表
  • 权限管理
  • 规则管理

角色 - 用户自己的表

这个在模块的配置项中进行配置

这里写图片描述

从上到下为

用户对应model,id的字段,用户名字段,展示名的字段,自定义展示列配置

通过这个配置,我们就将RBAC和我们自己系统的联系在了一起。

配置权限管理默认角色默认权限

这个配置的作用是让框架知道要采用的的权限配置方案。

中文

默认是显示英文的,修改模块文件

yii2-admin/Module.php

    public function init()
    {
        parent::init();
        if (!isset(Yii::$app->i18n->translations['rbac-admin'])) {
            Yii::$app->i18n->translations['rbac-admin'] = [
                'class' => 'yii\i18n\PhpMessageSource',
                'sourceLanguage' => 'en',
                'basePath' => '@mdm/admin/messages',
            ];
        }
        Yii::$app->language = 'zh-CN'; //模块默认加载中文

        //user did not define the Navbar?
        if ($this->navbar === null && Yii::$app instanceof \yii\web\Application) {
            $this->navbar = [
                ['label' => Yii::t('rbac-admin', 'Help'), 'url' => ['default/index']],
                ['label' => Yii::t('rbac-admin', 'Application'), 'url' => Yii::$app->homeUrl],
            ];
        }
        if (class_exists('yii\jui\JuiAsset')) {
            Yii::$container->set('mdm\admin\AutocompleteAsset', 'yii\jui\JuiAsset');
        }
    }

使用自己的layout

后台框架如果是自己写的,那么可能就会用自己写的外部的layout,修改位置在web.php中的模块配置中。

'admin' => [
            'class' => 'mdm\admin\Module',
            'layout' => 'left-menu',
            'mainLayout' => '@app/views/layouts/main_sys.php', //自己的layout
]

使用自己的layout出现的问题(重要)

原因:使用了自己layout文件,导致对应的bootstrap框架模块中的图标展示不出来,从而导致模块内的操作按钮展示不出来

解决方案:直接修改视图文件,采用自定义按钮

下面以item中的index.phpview举例

<?php

use yii\helpers\Html;
use yii\grid\GridView;
use mdm\admin\components\RouteRule;
use mdm\admin\components\Configs;

/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
/* @var $searchModel mdm\admin\models\searchs\AuthItem */
/* @var $context mdm\admin\components\ItemController */

$context = $this->context;
$labels = $context->labels();
$this->title = Yii::t('rbac-admin', $labels['Items']);
$this->params['breadcrumbs'][] = $this->title;

$rules = array_keys(Configs::authManager()->getRules());
$rules = array_combine($rules, $rules);
unset($rules[RouteRule::RULE_NAME]);

//自定义按钮部分,其中的class是符合自己的条件
$buttons=[
    'view' => function ($url, $model, $key) {
        return Html::a("查看", [$this->context->id.'/view', 'id'=>$model->name], ['class' => "btn btn-success ", 'title' => '查看']);
    },
    'update' => function ($url, $model, $key) {
        return Html::a("修改", [$this->context->id.'/update', 'id'=>$model->name], ['class' => "btn btn-primary ", 'title' => '修改']);
    },
    'delete' => function ($url, $model, $key) {
        return Html::a("删除", [$this->context->id.'/delete', 'id'=>$model->name], ['class' => "btn btn-danger ", 'title' => '删除'
            ,'aria-label'=>'删除','data-pjax'=>"0","data-confirm"=>"您确定要删除此项吗?","data-method"=>"post"]);
    },
];
$columns['buttons']=$buttons;

?>
<div class="role-index">
    <h1><?= Html::encode($this->title) ?></h1>
    <p>
        <?= Html::a(Yii::t('rbac-admin', 'Create ' . $labels['Item']), ['create'], ['class' => 'btn btn-success']) ?>
    </p>
    <?=
    GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            [
                'attribute' => 'name',
                'label' => Yii::t('rbac-admin', 'Name'),
            ],
            [
                'attribute' => 'ruleName',
                'label' => Yii::t('rbac-admin', 'Rule Name'),
                'filter' => $rules
            ],
            [
                'attribute' => 'description',
                'label' => Yii::t('rbac-admin', 'Description'),
            ],
            ['class' => 'yii\grid\ActionColumn',
                'buttons'=>$buttons], //自定义的按钮
        ],
    ])
    ?>
</div>

权限控制

我们通过yii2-admin中封装好的方法对访问进行拦截

这里我们写一个父类,然后在对应的类中继承它。

<?php

namespace app\common\controllers;

use Yii;
use yii\web\Controller;
use yii\web\HttpException;
use mdm\admin\components\Helper;

class RbacBaseController extends Controller
{
    public function beforeAction($action)
    {
        //没有登录则跳转到登录界面
        if (Yii::$app->user->isGuest) {
           return  $this->redirect(Yii::$app->urlManager->createUrl(Yii::$app->user->loginUrl));
        }

        $url = \Yii::$app->controller->module->id."/". \Yii::$app->controller->id."/".\Yii::$app->controller->action->id;

        //根据路由判断权限,没有权限则跳转到错误页面
        if(!Helper::checkRoute($url)){
            throw new HttpException(400,"你没有权限",400);
        }
        return parent::beforeAction($action);
    }
}

其中后台管理的根据用户权限展示对应菜单也是通过这个方法做的。

关于错误页面的自定义,本文不再展开。

猜你喜欢

转载自blog.csdn.net/diandianxiyu/article/details/81838803