Php 仅允许作者使用ACF在yii2中编辑其帖子
我正在使用访问控制过滤器进行访问管理,但无法完成一件事——例如,我如何才能只允许项目经理更新项目并禁止其他人使用它?我通过matchCallback进行了尝试,但在本例中,所有项目经理都可以更新任何项目,因为返回TRUE 类似的更经常需要的规则-如何允许用户更新/删除使用ACF编写的帖子Php 仅允许作者使用ACF在yii2中编辑其帖子,php,yii2,access-control,role,yii2-user,Php,Yii2,Access Control,Role,Yii2 User,我正在使用访问控制过滤器进行访问管理,但无法完成一件事——例如,我如何才能只允许项目经理更新项目并禁止其他人使用它?我通过matchCallback进行了尝试,但在本例中,所有项目经理都可以更新任何项目,因为返回TRUE 类似的更经常需要的规则-如何允许用户更新/删除使用ACF编写的帖子 'access' => [ 'class' => AccessControl::className(), 'only' =>
'access' => [
'class' => AccessControl::className(),
'only' => ['index', 'view', 'create', 'update', 'delete'],
'rules' => [
[
'actions' => ['update'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return Yii::$app->user->identity->getProjectParticipants()
->one()->isManager(Yii::$app->user->identity->id);
}
],
],
],
下面是我如何结合ACF和RBAC来实现它的。如果我错了或者有更好的方法,请纠正我。它基于基本模板
类PhpManager扩展\yii\rbac\PhpManager
{
公共函数init()
{
父::init();
}
公共函数getAssignments($userId)
{
如果(!Yii::$app->user->isGuest){
$assignment=新分配();
$assignment->userId=$userId;
#假设角色存储在用户表“角色”列中
$assignment->roleName=Yii::$app->user->identity->role;
返回[$assignment->roleName=>$assignment];
}
}
}
3.将authManager添加到web.app和console.app控制台文件。
#参考
# http://programming.peixoto.cf/2015/01/14/yii2-role-based-access-control-and-context-access-rule/#$$nmvkr0&&0SUmhOPVEeSW9grIhAgzZg$$
类ContextAccessRule扩展了AccessRule
{
公共模型类;
公共$primaryKey;
受保护的函数匹配角色($user)
{
if(父::匹配角色($user))
返回true;
$model=$this->findModel();
foreach($this->roles as$role){
#调用处理规则的CheckAccess()函数
如果($user->can($role,['model'=>$model])){
返回true;
}
}
返回false;
}
受保护函数findModel()
{
如果(!isset($this->modelClass))
抛出新的InvalidConfigException(Yii::t('app','modelClass'必须为“{class}”设置,['class'=>\uuuuu class]);
$primaryKey=$this->getPrimaryKey();
#获取请求参数
$queryParams=\Yii::$app->getRequest()->getQueryParams();
#加载模型
$model=call_user_func([$this->modelClass,'findOne',$queryParams[join(',',$primaryKey)];
如果($model!==null){
返回$model;
}否则{
抛出新的NotFoundHttpException(Yii::t('app','请求的页面不存在');
}
}
#获取模型的主键
受保护的函数getPrimaryKey()
{
如果(!isset($this->primaryKey)){
返回调用用户函数([$this->modelClass,'primaryKey']);
}否则{
返回$this->primaryKey;
}
}
这最好用自定义的AccessRule
来解决。必须填写代码以检查用户是否是项目的作者
namespace app\filters;
class AuthorAccessRule extends \yii\filters\AccessRule
{
public $allow = true; // Allow access if this rule matches
public $roles = ['@']; // Ensure user is logged in.
public function allows($action, $user, $request)
{
$parentRes = parent::allows($action, $user, $request);
// $parentRes can be `null`, `false` or `true`.
// True means the parent rule matched and allows access.
if ($parentRes !== true) {
return $parentRes;
}
return ($this->getProjectAuthorId($request) == $user->id);
}
private function getProjectAuthorId($request)
{
// Fill in code to receive the right project.
// assuming the project id is given à la `project/update?id=1`
$projectId = $request->get('id');
$project = \app\models\Project::findOne($projectId);
return isset($project) ? $project->author_id : null;
}
}
该规则可通过在行为中包含以下内容来使用:
'authorAccess' => [
'class' => AccessControl::className(),
'only' => ['update'],
'rules' => ['actions' => ['update']],
'ruleConfig' => ['class' => '\app\filters\AuthorAccessRule'],
],
它可以这样实现:
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
class MyController extends Controller
{
...
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['update', 'delete'],
'rules' => [
[
'actions' => ['update', 'delete'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
if (Yii::$app->user->can('admin') || $this->isUserAuthor()) {
return true;
}
return false;
}
],
],
],
];
}
protected function findModel($id)
{
if (($model = MyModel::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
protected function isUserAuthor()
{
return $this->findModel(Yii::$app->request->get('id'))->author->id == Yii::$app->user->id;
}
...
}
你找到解决办法了吗?
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
class MyController extends Controller
{
...
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['update', 'delete'],
'rules' => [
[
'actions' => ['update', 'delete'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
if (Yii::$app->user->can('admin') || $this->isUserAuthor()) {
return true;
}
return false;
}
],
],
],
];
}
protected function findModel($id)
{
if (($model = MyModel::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
protected function isUserAuthor()
{
return $this->findModel(Yii::$app->request->get('id'))->author->id == Yii::$app->user->id;
}
...
}