Yii2 RBAC规则反馈/消息

Yii2 RBAC规则反馈/消息,yii2,rbac,yii2-rbac,Yii2,Rbac,Yii2 Rbac,这是一个关于在Yii2中使用RBAC的问题 到目前为止,我发现它工作得相当好,令人满意,但是我缺少一个关键特性:Yii2规则以类似于Yii2验证器设置错误消息来解释验证失败原因的方式提供“反馈”的能力。我正在寻找一种方法来提供某种反馈,说明为什么不授予许可 特别是,该方法将返回一个布尔类型,这很好,但在检查权限时,我们不知道用户没有被授予该特定权限的确切原因 举一个更实际的例子。假设我们正在尝试确定当前用户是否可以提交评论。我们通常会这样做: if (Yii::$app->user->

这是一个关于在Yii2中使用RBAC的问题

到目前为止,我发现它工作得相当好,令人满意,但是我缺少一个关键特性:Yii2规则以类似于Yii2验证器设置错误消息来解释验证失败原因的方式提供“反馈”的能力。我正在寻找一种方法来提供某种反馈,说明为什么不授予许可

特别是,该方法将返回一个布尔类型,这很好,但在检查权限时,我们不知道用户没有被授予该特定权限的确切原因

举一个更实际的例子。假设我们正在尝试确定当前用户是否可以提交评论。我们通常会这样做:

if (Yii::$app->user->can('postComment',['comment'=>$comment])) {
    $comment->post();
} else {
    throw new ForbiddenHttpException('Sorry m8, you cant do this. No idea why tho!');
}

它工作得很好,但正如示例中所示,我们真的不知道用户为什么不能发布评论。可能有很多原因,例如因为线程被锁定,或者因为他们没有在某个类别中发布的权限,或者因为他们没有足够高的声誉等等,但是我们想告诉用户原因!所以我的问题是,我们如何从Yi2的RBAC中获得反馈?

您可能希望创建自己的AccessRule,并通过覆盖该类中的当前方法来设置场景中的消息异常<代码>匹配角色将是您要覆盖的方法。Yii2没有这个功能,因此您必须使用自己的AccessRule来实现

然后,在其创建后,将其连接到控制器:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'ruleConfig' => [
                'class' => 'app\components\AccessRule'
            ],
            'rules' => [
                /* my normal rules */
            ],
        ],
    ];
}

所以基本上我所做的就是添加

'message' => 'Current password cannot be blank.' 
遵守我的规则

请确保将正确的规则分开,这样您就不会在多个没有意义的字段中获得该消息。另外,请确保将其添加到“必需”规则中,除非您希望该消息在它是另一个规则时显示


我希望这对你们有所帮助,因为我花了太多时间搜索它。

从RBAC获取反馈的最快方法是将对象作为参数传递。如果检查失败,则将错误文本输入此对象。通过这种方式,可以获得测试结果为阴性的原因

假设我们想阻止用户评论他们的帖子

规则中的验证。此规则与
post comment
权限关联:

class PostCommentRule扩展了yii\rbac\Rule
{
public$name='PostCommentRuleName';
公共函数执行($user、$item、$params)
{
$allowed=$params['post']->owner\u id!==$user;
if(!$allowed&&isset($params['errorObject']))
$params['errorObject']->errorText='不允许对自己发表评论';
允许返回$;
}
}
我们检查许可,如果禁止,我们有理由:

$errorObject=new stdClass();
如果(Yii::$app->user->can('postComment',['post'=>$post,'errorObject'=>$errorObject])){
$comment->post();
}否则{
抛出新的禁止HttpException($errorObject->errorText);
}

在您的情况下,我将创建一个基本权限类,该类将使用一个简单的方法覆盖特定限制消息的抽象,并通过您的所有权限进行扩展

这是抽象的许可蓝图

abstract class AbstractPermission extends Permission
{
    /**
     * @return string
     */
    abstract public function getRestrictionMessage(): string;
}
创建自定义数据库管理器以检查检索到的权限是否实现了抽象

class CustomDbManager extends DbManager 
{
    /**
     * @throws \Exception
     * @return AbstractPermission|null
     */
    public function getPermission($name): ?AbstractPermission 
    {
        $permission = parent::getPermission($name);

        if ($permission === null) {
            return null;
        }

        if (!$permission instanceof AbstractPermission) {
            throw new \Exception(
                'Your permission class should be derived from ' . AbstractPermission::class
            );
        }

        return $permission;
    }
}
在配置文件中定义
CustomDbManager

'components' => [
    'authManager' => [
        'class' => CustomDbManager::class
    ],
    ...
];
您的
PostCommentPermission
示例

class PostCommentPermission extends AbstractPermission
{
    /**
     * @return string
     */
    public function getRestrictionMessage(): string
    {
        return 'You cannot post comments!';
    }
}
最后通过特定的权限检查调用您的经理

$authManager = Yii::$app->getAuthManager();

$postCommentPermission = $authManager->getPermission('postComment');

if (Yii::$app->user->can($postCommentPermission->name, ['comment' => $comment])) {
    $comment->post();
} else {    
    throw new ForbiddenHttpException($postCommentPermission->getRestrictionMessage());
}

通常,当用户没有权限或者您可以编写自定义消息,或者使用try-catch时,RBAC会给出
禁止的
异常。Yi2中的RBAC不会这样做。它只返回是/否(布尔)答案。然后由程序员根据最少的信息抛出异常。只有在用户没有后命令权限时才会抛出错误。好吧,谢谢,但我要寻找的不仅仅是一个糟糕的解决方法。不幸的是,这不是一个真正的选项,因为我需要在任何地方使用权限检查,而不仅仅是控制器(也包括引导、组件、小部件、模型等)。它们都有行为或可以附加行为。我刚刚意识到这个答案是关于验证规则的,与我的问题lol无关。我问的是添加反馈消息RBAC规则对象,而不是模型验证规则。没有以任何方式回答问题!这与原始问题无关。
yii\filters\AccessRule
没有
消息
属性。