【问题标题】:How to hide admin account from other users如何对其他用户隐藏管理员帐户
【发布时间】:2018-03-07 05:27:26
【问题描述】:

我正在处理yii2。我有一些user roles。管理员拥有所有级别的访问权限。其他用户的访问级别较低。有一个其他用户可见的用户列表。在此列表中,系统中用户的所有详细信息均可用。现在,我想对其他用户隐藏一些用户信息。我要隐藏的角色是1,6,7,8,我要隐藏的角色是5。除了提到的用户角色之外,5 应该可以看到。为此,我更新了索引控制器。

 $searchModel = new UserSearch();

    $queryParams=Yii::$app->request->queryParams;
    //check if user or one of the managers
    $isAdmin=in_array(Yii::$app->user->identity->user_role,[1]);

    //set params if normal user
    if(!$isAdmin){
        $queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5]);
    }

    $dataProvider = $searchModel->search($queryParams);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider
    ]);

现在在运行我的项目时,我只看到管理员用户。在$queryParams['UserSearch']['user_role']= 中,我尝试传递用户角色5 的单个值,它只显示5 角色用户。但我想向角色2,3,4,5 的用户展示。

更新 1

我的搜索模型

class UserSearch extends User
{
/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['id','group_id'], 'integer'],
        [['email','username', 'name','contact_number','group_id','user_role'], 'safe'],
    ];
}

/**
 * @inheritdoc
 */
public function scenarios()
{
    // bypass scenarios() implementation in the parent class
    return Model::scenarios();
}

/**
 * Creates data provider instance with search query applied
 *
 * @param array $params
 *
 * @return ActiveDataProvider
 */
public function search($params)
{
    $query = User::find();

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $this->load($params);

    if (!$this->validate()) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere([
        'id' => $this->id,
        'status' => $this->status,
    ]);

    $query->andFilterWhere(['like', 'id', $this->id])
        ->andFilterWhere(['like', 'name', $this->name])
        ->andFilterWhere(['like', 'username', $this->username])
        ->andFilterWhere(['like', 'email', $this->email])
        ->andFilterWhere(['like', 'contact_number', $this->contact_number])
        ->andFilterWhere(['=', 'user_role', $this->user_role])
        ->andFilterWhere(['=', 'group_id', $this->group_id]);


   // $query->andFilterWhere(['=','user_type','user']);
    if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
        $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
    }
    //$query->andFilterWhere(['!=', 'id', Yii::$app->user->id]);

    return $dataProvider;
}
 }

任何帮助将不胜感激。

【问题讨论】:

  • 您是否打算将$queryParams['UserSearch']['user_role'] 值设置为布尔值?这是in_array() 将返回的内容。
  • 不,我不想这样做
  • 我认为传递 user_role 的数组是不够的 .. 你应该看看你的 searchModelsearch 中的过滤器如何工作来管理数组 .. 你通过了
  • 广告您的搜索模型
  • @MuhammadOmerAslam 添加了

标签: yii2 yii2-advanced-app access-control yii2-user yii2-user-roles


【解决方案1】:

换行

$queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5]);

$queryParams['UserSearch']['user_role']=in_array(Yii::$app->user->identity->user_role,[2,3,4,5])?[1,6,7,8]:'';

并在您的搜索模型中更改条件

->andFilterWhere(['=', 'user_role', $this->user_role])

->andFilterWhere(['NOT IN', 'user_role', $this->user_role])

所以你的 search() 方法看起来像

public function search( $params ) {
    $query = User::find ();

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider ( [
        'query' => $query ,
    ] );

    $this->load ( $params );

    if ( !$this->validate () ) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere ( [
        'id' => $this->id ,
        'status' => $this->status ,
    ] );

    $query->andFilterWhere ( [ 'like' , 'id' , $this->id ] )
            ->andFilterWhere ( [ 'like' , 'name' , $this->name ] )
            ->andFilterWhere ( [ 'like' , 'username' , $this->username ] )
            ->andFilterWhere ( [ 'like' , 'email' , $this->email ] )
            ->andFilterWhere ( [ 'like' , 'contact_number' , $this->contact_number ] )
            ->andFilterWhere ( [ 'NOT IN' , 'user_role' , $this->user_role ] )
            ->andFilterWhere ( [ '=' , 'group_id' , $this->group_id ] );


    // $query->andFilterWhere(['=','user_type','user']);
    if ( Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != '' ) {
        $query->andFilterWhere ( [ '=' , 'group_id' , Yii::$app->user->identity->group_id ] )->andWhere ( 'user_role=4' );
    }
    //$query->andFilterWhere(['!=', 'id', Yii::$app->user->id]);

    return $dataProvider;
}

【讨论】:

  • 这个答案很有帮助。感谢您的帮助
【解决方案2】:

如果所有搜索到的模型项都应隐藏/显示安全信息,您可以向search() 函数添加第二个选项,该选项将在查询构建时显示隐藏安全信息。例如:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams,
        Yii::$app->user->identity->user_role === User::ADMIN_ROLE);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

或者您可以在控制器中添加查询条件:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    if(Yii::$app->user->identity->user_role === User::ADMIN_ROLE) {
        $dataProvider->query->andWhere(/* come condition*/);
    }

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

如果您的项目将在其他代码位置使用访问控制,强烈建议使用默认 Yii2 配置中包含的Role Based Access Control (RBAC)。使用这个未来,您只需在user 表中检查用户权限而无需额外列。它可能看起来像这样:

    $searchModel = new UserSearch();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    if(Yii::$app->user->can(Roles::USER_VIEW_PRIVATE_INFO)) {
        $dataProvider->query->andWhere(/* come condition*/);
    }

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

【讨论】:

    【解决方案3】:

    为什么要使用控制器更改 index 视图?正如我所看到的,在您的搜索类中已经检查了user role

     if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
            $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
        }
    

    在这之后你可以添加

    if(Yii::$app->user->identity->user_role == Roles::ROLE_INVENTORY_MANAGEMENT && Yii::$app->user->identity->group_id =='')
        {
            $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role IN (2,3,4,5)');
        }
    

    所以你的最终代码会是这样的

    if(Yii::$app->user->identity->user_role == Roles::ROLE_TEAM_LEAD && Yii::$app->user->identity->group_id != ''){
            $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role=4');
        }
        else if(Yii::$app->user->identity->user_role == Roles::ROLE_INVENTORY_MANAGEMENT && Yii::$app->user->identity->group_id =='')
        {
            $query->andFilterWhere(['=','group_id', Yii::$app->user->identity->group_id])->andWhere('user_role IN (2,3,4,5)');
        }
    

    我希望这也适用于您的过滤器:)

    【讨论】:

    • 感谢您的建议@moeez bhai :)
    猜你喜欢
    • 2013-08-04
    • 2022-02-16
    • 2013-11-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 2015-08-27
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多