这是关于Yii2中RBAC使用的问题。
到目前为止,我发现它工作得相当好并且令人满意,但是我缺少一个关键功能:Yii2规则提供"反馈"以与Yii2 Validators类似的方式设置错误消息以解释验证失败的原因。我正在寻找一种方法来提供某种反馈,说明为什么没有授予许可。
特别是,can()方法会返回布尔类型,这很好,但在检查权限时,我们不知道为什么完全是用户没有被授予特别许可。
举一个更实际的例子。我们假设我们正在尝试确定当前用户是否可以提交评论。我们通常会这样做:
jQuery.when( deferreds )
效果很好,但如示例所示,我们真的不知道为什么用户无法发表评论。可能有多种原因,例如因为线程被锁定或者因为他们没有在某个类别中发布的权限,或者因为他们没有足够高的声誉等等。但我们想告诉用户原因!所以我的问题是,我们如何从Yii2的RBAC获得反馈?
答案 0 :(得分:1)
基本上我所做的就是添加
Select ID_Client
, Counter
, Length, Amount
, sum(Counter) over (Partition by ID_CLIENT order by ID_Client, Date_from) as Value1
, Amount - sum(Counter) over (Partition by ID_CLIENT order by ID_Client, Date_From) as Value2
, Date_from
, Date_To
from TableName
order by ID_Client, Date_From, Date_To
遵守我的规则。
确保您分离正确的规则,因此您不会在多个字段上获取该消息,而这些字段没有意义。另外,请确保将其添加到“必需”规则中,除非您希望该消息在其他规则时显示..
我希望这对你们有所帮助,因为我花了太多时间寻找它。
答案 1 :(得分:0)
您可能希望创建自己的AccessRule,并通过覆盖该类中的当前方法来设置场景中的消息异常。 matchRole
将是你要覆盖的方法。 Yii2没有这个,所以你必须滚动你自己的AccessRule才能这样做。
然后,一旦创建它将它附加到您的控制器:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'ruleConfig' => [
'class' => 'app\components\AccessRule'
],
'rules' => [
/* my normal rules */
],
],
];
}
答案 2 :(得分:0)
从RBAC获得反馈的最快方法是将对象作为参数传递。如果检查失败,则将错误文本输入该对象。这样,可以得出测试结果为阴性的原因。
假设我们要阻止用户对自己的信息发表评论。
规则验证。该规则与postComment
权限相关联:
class PostCommentRule extends yii\rbac\Rule
{
public $name = 'PostCommentRuleName';
public function execute($user, $item, $params)
{
$allowed = $params['post']->owner_id !== $user;
if(!$allowed && isset($params['errorObject']))
$params['errorObject']->errorText = 'Comments to oneself are not allowed.';
return $allowed;
}
}
我们检查许可,如果有禁止,我们有一个理由:
$errorObject = new stdClass();
if (Yii::$app->user->can('postComment',['post'=>$post,'errorObject'=>$errorObject])) {
$comment->post();
} else {
throw new ForbiddenHttpException($errorObject->errorText);
}
答案 3 :(得分:0)
在您的情况下,我将创建一个基本权限类,该基本权限类将使用一种简单的方法涵盖特定限制消息的抽象,并且将通过所有权限进行扩展。
这是抽象许可蓝图。
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());
}