Программирование, веб-кодинг

Yii2-user сменить текущего пользователя или переход на другого пользователя (SwitchIdentity)

Impersonate User / Become another user

Возникла необходимость переключиться под админом на другого пользователя, то есть авторизоваться в системе под другим пользователем и видеть его личный кабинет.

Yii2-user сменить текущего пользователя или переход на другого пользователя (SwitchIdentity)

Но при этом нужно сохранить админский доступ, чтобы видеть и иметь возможность изменять расширенные настройки для какого-либо пользователя. В моём случае это - корректировать программу тренировок для конкретного клиента и некоторые поля в его настройках.

Возможно, это не лучший вариант организации доступа, но мне нужно видеть глазами самого клиента его личный кабинет.

C расширением Yii2-user

Это делается по документации к расширению переходом по ссылке /user/admin/switch с передачей идентификатора нужного пользователя (id) в post-запросе. Обратно вернуться к админу - вызвать то же, но без id.

Для ссылки, например, в GridView будет:

[
            'header' => Yii::t('user', 'Switch'),
            'value' => function ($model) {
                    return Html::a('<i class="bi bi-box-arrow-in-right"></i> '.Yii::t('user', 'Switch'), ['switch', 'id' => $model->id], [
                        'class' => 'btn btn-xs btn-success btn-block',
                        'data-method' => 'post',
                    ]);
            },
            'format' => 'raw',
        ],

Обратно переключиться на админа:

if (Yii::$app->session->has(\dektrium\user\controllers\AdminController::ORIGINAL_USER_SESSION_KEY))
    echo Html::a(
    '<span class="glyphicon glyphicon-user"></span> Back to original user',
     ['/user/admin/switch'], ['class' => 'btn btn-primary', 'data-method' => 'POST']);

или:

echo Nav::widget([
    'items' => [
        Yii::$app->session->has(\dektrium\user\controllers\AdminController::ORIGINAL_USER_SESSION_KEY;) ?
        '' . Html::beginForm(['/user/admin/switch'], 'post', ['class' => 'navbar-form'])
            . Html::submitButton('<span class="glyphicon glyphicon-user"></span> Back to original user',
                ['class' => 'btn btn-link']
            ) . Html::endForm() . '' : '',
      ],


Для того, чтобы сделать проверку админ ли первоначальный пользователь (родитель), делаю так:

if(Yii::$app->session->has(\dektrium\user\controllers\AdminController::ORIGINAL_USER_SESSION_KEY )) {
    $userr = app\models\User::findOne(Yii::$app->session->get(\dektrium\user\controllers\AdminController::ORIGINAL_USER_SESSION_KEY));
    if($userr->isAdmin)
        // тут ваши действия, если вы изначально под админом логинились, например,     
        // вывожу поле level для редактирования админом (сам пользователь не может редактировать это поле, поэтому ему оно не показывается)         
        echo $form->field($model, 'level')->dropDownList(app\models\BaseModel::getLevelsArray());
}

или проще так:

if(Yii::$app->session->has(\dektrium\user\controllers\AdminController::ORIGINAL_USER_SESSION_KEY )) {
 $originaluserisadmin = true;
} else {$originaluserisadmin = false;}


Без расширений

Туда:

$initialId = Yii::$app->user->getId(); //here is the current ID, so you can go back after that.
if ($id == $initialId) {
    //Same user!
} else {
    $user = User::findOne($id);
    $duration = 0;
    Yii::$app->user->switchIdentity($user, $duration); //Change the current user.
    Yii::$app->session->set('user.idbeforeswitch',$initialId); //Save in the session the id of your admin user.
    return $this->render('index'); //redirect to any page you like.
}

Здесь $id - это id пользователя, на которого хотите переключиться.

Обратно:

$originalId = Yii::$app->session->get('user.idbeforeswitch');
if ($originalId) {
$user = User::findOne($originalId);
$duration = 0;
Yii::$app->user->switchIdentity($user, $duration);
Yii::$app->session->remove('user.idbeforeswitch');
}
return $this->render('index');


Ещё по теме:


Читайте также