所以,我的小Yii2应用程序有测验。每个quiz
属于一个user
,user
有许多quizzes
标准内容。我想要做的是限制用户更新或删除不属于他们的测验。简单明了。
现在,我意识到,这种称为RBAC的东西有特定的解决方案,但我仍然不想处理角色并设置所有东西。
所以我决定创建一个小的自定义过滤器来执行此操作。
namespace frontend\components;
use ...
class UserOwnerAccessControlFilter extends ActionFilter
{
public function beforeAction($action)
{
if (Yii::$app->getUser()->isGuest) {
return Yii::$app->getResponse()->redirect(['site/login']);
}
$user = Yii::$app->getUser()->identity;
$controllerID = $action->controller->id;
if ($controllerID == 'quiz') {
$quiz = Quiz::findOne(['id'=> Yii::$app->getRequest()->queryParams['id']]);
if ($quiz->user_id != $user->id) {
throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
return false;
}
} elseif ($controllerID == 'chapter') {
//TODO
}
return parent::beforeAction($action);
}
public function afterAction($action, $result)
{
return parent::afterAction($action, $result);
}
}
当然,我也在quiz
控制器的行为中添加了一些行:
public function behaviors()
{
return [
...
[
'class' => UserOwnerAccessControlFilter::className(),
'only' => ['update', 'delete'],
]
];
}
正如您从上面所看到的,此过滤器仅适用于update
和delete
操作。
现在,我已经测试了所有这些,非常彻底,我收到了结果:
当我使用用户quiz
创建A
时,请使用用户B
登录并尝试编辑或删除quiz
,过滤器工作正常。我得到ForbiddenHttpException
完全符合我的想法。
当我使用用户quiz
创建A
时,请注销,然后尝试访问quiz/update
页面(使用GET
http请求){{ 1}}未经身份验证,我被重定向到quiz
。正如我想的那样。
现在,当我创建一个site/login
用户quiz
,注销并未经身份验证时,通过进行攻击并提出A
请求POST
或update
操作,过滤器无效!1 并且请求通过。
现在,我是PHP和Yii的新手(是的,我已经讨厌它了),所以以下是我的delete
代码,也许它与此有关:
urlManager
有人可以对此有任何想法吗?提前谢谢。