名为 ‘isAuthor‘ 的规则到底是干什么的?规则内容具体是什么?

1. 名为 'isAuthor' 的规则到底是干什么的?

(1) 作用
  • 动态权限判定
    • 'isAuthor' 规则用于判断当前用户是否是某个对象(如文章)的创建者。
    • 它通过检查上下文参数(如文章的 created_by 属性)来实现动态权限控制。
(2) 使用场景
  • 文章管理

    • 示例:
      • 只有文章的作者才能修改或删除自己的文章。
  • 订单管理

    • 示例:
      • 用户只能查看或编辑自己创建的订单。
  • 部门审批

    • 示例:
      • 部门经理只能审批本部门的报销单。

2. 规则内容具体是什么?

以下是一个典型的 'isAuthor' 规则的实现:

<?php

namespace app\rbac;

use yii\rbac\Rule;

/**
 * AuthorRule 类用于检查当前用户是否是文章的作者。
 */
class AuthorRule extends Rule
{
    // 定义规则的名称
    public $name = 'isAuthor'; 

    /**
     * execute 方法用于实现动态权限检查。
     * @param int|string $user 用户 ID,表示当前用户。
     * @param Item $item 权限或角色对象,表示当前检查的权限或角色。
     * @param array $params 传递的上下文参数,包含与权限判定相关的信息。
     * @return bool 返回 true 表示满足规则,返回 false 表示不满足规则。
     */
    public function execute($user, $item, $params)
    {
        // 检查 $params 数组中是否存在键名为 'post' 的元素
        // 作用:确保传递的上下文参数中包含了文章对象(或类似的数据结构)。
        // 原因:如果没有传递 'post' 参数,直接访问 $params['post'] 会导致错误。
        // 知识点:PHP 的 isset() 函数,用于检查变量是否已设置且非 null。
        if (!isset($params['post'])) { 
            return false; 
        }

        // 获取 $params['post'] 对象的 created_by 属性
        // 作用:获取文章的创建者 ID,用于与当前用户的 ID 进行比较。
        // 原因:规则的核心逻辑是判断当前用户是否是文章的创建者。
        // 知识点:PHP 的对象属性访问语法($object->property)。
        $postCreatedBy = $params['post']->created_by;

        // 判断文章的创建者 ID 是否等于当前用户的 ID
        // 作用:验证当前用户是否是文章的创建者。
        // 原因:只有文章的创建者才能满足规则条件。
        // 知识点:PHP 的比较运算符(==),用于判断两个值是否相等。
        return $postCreatedBy == $user;
    }
}

3. 底层原理

(1) 数据存储
  • auth_rule 表结构

    CREATE TABLE auth_rule (
        name VARCHAR(64) NOT NULL PRIMARY KEY, -- 规则名称
        data TEXT,                             -- 规则对象序列化后的数据
        created_at INTEGER,                    -- 创建时间戳
        updated_at INTEGER                     -- 更新时间戳
    );
    
  • 字段说明

    • name:规则的唯一标识符(如 'isAuthor')。
    • data:规则对象序列化后的数据(通常是 PHP 对象)。
(2) 程序流

当调用 $auth->checkAccess($userId, $permissionName, $params) 时,系统会执行以下步骤:

  1. 加载权限信息

    • auth_item 表中加载目标权限的元信息。
  2. 检查规则绑定

    • 如果权限绑定了规则(rule_name 字段非空),从 auth_rule 表中加载对应的规则。
  3. 反序列化规则

    • auth_rule 表中的 data 字段反序列化为 PHP 对象。
  4. 调用规则逻辑

    • 调用规则对象的 execute() 方法,并传递用户 ID、权限对象和上下文参数。
  5. 返回结果

    • 根据 execute() 方法的返回值决定是否授予权限。
(3) 数据流
  • 写入数据

    • 当将规则添加到 RBAC 系统时,规则对象会被序列化并存储到 auth_rule 表中。
  • 读取数据

    • 当调用 $auth->checkAccess() 时,规则对象会被从 auth_rule 表中加载并反序列化。

4. 示例代码及详细注释

以下是一个完整的示例,展示如何使用 'isAuthor' 规则并附上详细注释。

<?php

namespace app\rbac;

use yii\rbac\Rule;

/**
 * AuthorRule 类用于检查当前用户是否是文章的作者。
 */
class AuthorRule extends Rule
{
    // 定义规则的名称
    public $name = 'isAuthor'; 

    /**
     * execute 方法用于实现动态权限检查。
     * @param int|string $user 用户 ID,表示当前用户。
     * @param Item $item 权限或角色对象,表示当前检查的权限或角色。
     * @param array $params 传递的上下文参数,包含与权限判定相关的信息。
     * @return bool 返回 true 表示满足规则,返回 false 表示不满足规则。
     */
    public function execute($user, $item, $params)
    {
        // 检查 $params 数组中是否存在键名为 'post' 的元素
        if (!isset($params['post'])) { 
            return false; 
        }

        // 获取 $params['post'] 对象的 created_by 属性
        $postCreatedBy = $params['post']->created_by;

        // 判断文章的创建者 ID 是否等于当前用户的 ID
        return $postCreatedBy == $user;
    }
}

// 获取 authManager 组件
// 作用:从 Yii2 应用中获取 RBAC 系统的管理器组件。
// 原因:authManager 是 Yii2 提供的 RBAC 核心组件,负责管理角色、权限和规则。
// 知识点:Yii2 的服务定位器机制,通过 \Yii::$app 访问应用组件。
$auth = \Yii::$app->authManager;

// 创建规则对象
// 作用:实例化 AuthorRule 类,用于定义动态权限检查逻辑。
// 原因:AuthorRule 是一个自定义规则,用于判断用户是否是文章的作者。
// 知识点:PHP 的类实例化语法(new 关键字)。
$rule = new \app\rbac\AuthorRule();

// 添加规则到 RBAC 系统
// 作用:将规则对象存储到 RBAC 系统中,以便后续使用。
// 原因:只有将规则添加到 RBAC 系统中,才能在权限检查时调用其逻辑。
// 知识点:Yii2 的 addRule() 方法,用于将规则存储到数据库中。
$auth->addRule($rule);

// 创建权限对象
// 作用:定义一个名为 "update-own-post" 的权限,表示更新自己文章的操作。
// 原因:权限是 RBAC 系统的基本单元,用于描述用户可以执行的操作。
// 知识点:Yii2 的 createPermission() 方法,用于创建权限对象。
$permission1 = $auth->createPermission('update-own-post');

// 设置权限描述
// 作用:为权限对象添加描述信息,便于理解和管理。
// 原因:描述信息可以帮助开发者和管理员快速了解权限的作用。
// 知识点:PHP 的属性赋值语法。
$permission1->description = 'Update own post';

// 绑定规则
// 作用:将规则 "isAuthor" 绑定到权限 "update-own-post"。
// 原因:通过规则可以实现动态权限检查,例如判断用户是否是文章的作者。
// 知识点:Yii2 的 rule_name 字段用于存储规则名称。
$permission1->ruleName = 'isAuthor'; 

// 将权限添加到 RBAC 系统
// 作用:将权限对象存储到 RBAC 系统中,以便后续使用。
// 原因:只有将权限添加到 RBAC 系统中,才能在权限检查时使用。
// 知识点:Yii2 的 add() 方法,用于将权限存储到数据库中。
$auth->add($permission1);

// 检查用户权限
// 作用:检查用户 ID 为 1 的用户是否拥有 "update-own-post" 权限。
// 原因:通过权限检查,可以动态控制用户的操作权限。
// 知识点:Yii2 的 checkAccess() 方法,用于判断用户是否拥有指定权限。
$post = new \stdClass();
$post->created_by = 1; // 假设文章的创建者是用户 ID 为 1 的用户
$params = ['post' => $post];

if ($auth->checkAccess(1, 'update-own-post', $params)) {
    echo "用户可以更新自己的文章";
} else {
    echo "用户无权更新文章";
}

5. 注意事项

(1) 上下文参数的重要性
  • $params 必须包含与权限判定相关的动态数据。
  • 示例:
    $post = Post::findOne(1); // 获取文章对象
    $params = ['post' => $post];
    
(2) 性能优化
  • 规则的 execute() 方法会在每次权限检查时被调用。
  • 避免在规则中执行耗时的操作(如复杂的数据库查询)。
(3) 缓存清理
  • 如果启用了缓存功能,在添加或修改规则后需要清理缓存以确保最新的规则生效。

6. 总结

  • 作用

    • 判断当前用户是否是某个对象的创建者(如文章的作者)。
  • 使用场景

    • 动态权限判定。
    • 细粒度权限控制。
    • 规则复用。
  • 底层原理

    • 数据存储在 auth_rule 表中。
    • 规则对象被序列化后存储。
    • 权限检查时加载并反序列化规则。
  • 程序流和数据流

    • 写入数据:规则对象被序列化并存储到 auth_rule 表中。
    • 读取数据:规则对象被从 auth_rule 表中加载并反序列化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值