YII2 博客系统

用户管理

  • 认证
  • 前后台认证分离
  • 用户管理页面完善
  • 授权

授权

授权是指验证用户是否允许做某件事情的设定,YII提供两种授权方法:

  • ACF 存取控制过滤器
  • RBAC 基于角色的存取控制

ACF存取控制过滤器

ACF是一种通过yii\filters\AccessControl类来实现的简单授权方法,非常适用于仅需简单存取控制的应用。

实现ACF的方法

public function behaviors()
{
  return [
    'access'=>[
      'class'=>AccessControl::className(),
      //权限规则
       'rules'=>[
            //登录时检测是否为未认证用户
           [
              'actions'=>['login', 'error'], //动作
              'allow'=>true,
              'roles'=>['?'] //角色
            ],
            // 退出时检测用户是否为认证用户
            [
                'actions'=>['logout', 'index'],
                'allow'=>true,
                'roles'=>['@']
            ]
        ]
    ]
  ];
}

在控制器中behaviors()中设定存取的规则,当用户请求一个动作时,ACF会检查存取规则,判断该用户是否被允许执行所请求的动作。

ACF角色类型(roles)

  • ?表示未经认证的访客用户
  • @表示已认证用户。

ACF存取规则(rules)

  • ips 浏览器的IP地址,可使用通配符*,为空表示匹配所有IP。
  • verbs 匹配请求方式,如GET、POST。
  • matchCallback PHP回调,以确定应用该规则。
  • denyCallback PHP回调,当规则禁止访问时被访问。

RBAC基于角色存取控制

RBAC基于角色存取控制
  • 集中式存取控制机制
  • 角色是权限的集合
  • 角色和权限都实现了树的层次结构

权限检查

  • 一个角色可指派给一个或多个用户
  • 系统会检查包含该权限的角色是否指派给该用户

规则

  • 规则可是一段代码用来与一个角色或权限关联
  • 通过规则的执行检查一个用户是否满足角色或权限要求

实现

  • 建立授权数据
    配置应用组件authManageryii\rbac\DbManager
    common\config\main.php
'components'=>[
  'authManager'=>['class'=>'yii\rbac\DbManager']
]

使用数据迁移创建表

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

数据迁移后会在数据库中新增四张表
(1)auth_assignment 指派角色给用户
(2)auth_item 角色表 type=1为父 type=2为子
(3)auth_item_child 角色父子树
(4)auth_rule 规则

通过authManager提供的API创建一个控制台命令,初始化授权数据。
console/controllers/RbacController.php

<?php
namespace console\controllers;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        //添加权限
        $createPost = $auth->createPermission('createPost');
        $createPost->description = '创建文章';
        $auth->add($createPost);

        $updatePost = $auth->createPermission('updatePost');
        $updatePost->description = '更新文章';
        $auth->add($updatePost);

        $deletePost = $auth->createPermission('deletePost');
        $deletePost->description = '删除文章';
        $auth->add($deletePost);

        $approveComment = $auth->createPermission('approveComment');
        $approveComment->description = '审核评论';
        $auth->add($approveComment);

        //添加角色并授权
        $postAdmin = $auth->createRole('postAdmin');
        $postAdmin->description = '文章管理员';
        $auth->add($postAdmin);
        $auth->addChild($postAdmin, $createPost);
        $auth->addChild($postAdmin, $updatePost);
        $auth->addChild($postAdmin, $deletePost);

        $postOperator = $auth->createRole('postOperator');
        $postOperator->description = '文章操作员';
        $auth->add($postOperator);
        $auth->addChild($postOperator, $deletePost);

        $commentAuditor = $auth->createRole('commentAuditor');
        $commentAuditor->description = '评论审核员';
        $auth->add($commentAuditor);
        $auth->addChild($commentAuditor, $approveComment);

        $admin = $auth->createRole('admin');
        $admin->description = '系统管理员';
        $auth->add($admin);
        $auth->addChild($admin, $postAdmin);
        $auth->addChild($admin, $postOperator);
        $auth->addChild($admin, $commentAuditor);

        //为用户指派角色
        $auth->assign($admin, 1);
        $auth->assign($postAdmin, 2);
        $auth->assign($postOperator, 3);
        $auth->assign($commentAuditor, 4);
    }
}

控制台执行

yii rbac/init
  • 执行权限规则
    对新增文章进行权限检查
    controllers/PostController.php
    //引入异常处理类
    use yii\web\ForbiddenHttpException;

    //创建文章
    public function actionCreate()
    {
        if(!Yii::$app->user->can('createPost')){
            throw new ForbiddenHttpException('权限不足,禁止操作!');
        }

        $model = new Post();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

yii\web\User::can()是一种快捷用法,用于对当前登录用户进行权限检查,若要能对任何用户进行权限检查,需调用yii\rbac\ManagerInterface::checkAccess()来检查权限。

权限设置页面

创建auth_assignmentauth_item的公共模型类

auth_assignment
auth_item
授权操作

账户管理控制器中添加授权操作
backend/Controllers/adminController.php

use backend\models\AuthItem;
use backend\models\AuthAssignment;

public function actionPrivilege($id)
{
    //获取所有权限
    $allPrivilegesArray = array();
    $allPrivileges = AuthItem::find()->select(['name','description'])->where(['type'=>1])->orderBy('description')->all();
    foreach($allPrivileges as $item){
        $allPrivilegesArray[$item->name] = $item->description;
    }
    //获取当前用户权限
    $AuthAssignmentsArray = array();
    $AuthAssignments = AuthAssignment::find()->select(['item_name'])->where(['user_id'=>$id])->all();
    foreach($AuthAssignments as $item){
        array_push($AuthAssignmentsArray, $item->item_name);
    }

    //从表单提交的数据来更新auth_assignment表,从而用户的角色发生变化
    if(isset($_POST['privs'])){
        AuthAssignment::deleteAll('user_id=:id', [':id'=>$id]);

        $privs = $_POST['privs'];
        for($i=0; $i<count($privs); $i++){
            $priv = new AuthAssignment();
            $priv->item_name = $privs[$i];
            $priv->user_id = $id;
            $priv->created_at = time();

            $priv->save();
        }
        return $this->redirect(['index']);
    }

    //渲染多选按钮
    return $this->render('privilege',[
        'id'=>$id,
        'AuthAssignmentsArray'=>$AuthAssignmentsArray,
        'allPrivilegesArray'=>$allPrivilegesArray
    ]);
}

添加账户管理设置页面
backend/views/privilege.php

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$this->title = '权限控制';
$this->params['breadcrumbs'][] = ['label' => '权限设置', 'url' => ['index']];
$this->params['breadcrumbs'][] = '更新';
?>
<div class="admin-privilege ">
    <h1><?= Html::encode($this->title) ?></h1>
    <div class="admin-privilege-form">
        <?php $form = ActiveForm::begin(); ?>
        <?= Html::checkboxList('privs', $AuthAssignmentsArray, $allPrivilegesArray) ?>
        <div class="form-group">
            <?= Html::submitButton('更新', ['class' => 'btn btn-success']) ?>
        </div>
        <?php ActiveForm::end(); ?>
    </div>
</div>

前台建立

  • 首页
  • 文章页

首页

使用前台脚手架 /frontend/web/index.php?r=gii生成文章CRUD操作。

文章

修改前台默认首页地址
frontend/config/main.php

return [
  'defaultRoute'=>'post/index',
  'language'=>'zh-CN',
]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341