Реализация метода «логин под другим юзером» в yii2

Допустим, вы вошли на сайт как администратор, но ваша цель - выдать себя за другого пользователя. Это может быть полезно, если вы хотите узнать, как приложение выглядит и "ведет себя" себя при просмотре другим пользователем.

Источник: How to do identity impersonation with Yii2.

Вначале работы настройки компонента user (config/web.php) Вашего приложения должны выглядеть примерно так:

return [
    'components' => [
        'user' => [
            'identityClass' => app\models\User',
        ]
    ]
];

Для облегчения работы с пользовательским компонентом переопределим пользовательский класс приложения по умолчанию и поместим в него некоторые полезные методы. Давайте назовем этот класс WebUser, чтобы избежать путаницы между пользователем Active Record и пользователем приложения.

Добавим компонент:

namespace app\components;

use Yii;
use yii\web\User;

class WebUser extends User
{
    const IDENTITY_ID_KEY = 'mainIdentityId';
    const ADMIN_PERMISSION = 'admin';

    public function getIsImpersonated()
    {
        return !is_null(Yii::$app->session->get(self::IDENTITY_ID_KEY));
    }

    public function setMainIdentityId($userId)
    {
        Yii::$app->sesion->set(self::IDENTITY_ID_KEY, $userId);
    }

    public function getMainIdentityId()
    {
        $mainIdentityId = Yii::$app->session->get(self::IDENTITY_ID_KEY);
        return !empty($mainIdentityId) ? $mainIdentityId : $this->getId();
    }

    public function getIsAdmin()
    {
        return !$this->getIsGuest() && $this->can(self::ADMIN_PERMISSION);
    }
}

Обновим настройки:

return [
    'components' => [
        'user' => [
              'class' => 'app\components\WebUser'         
             'identityClass' => app\models\User',
        ]
    ]
];

Чтобы залгониться под другим пользователем, нужно создать два отдельных действия внутри UserController. Первое действие - actionImpersonate и оно будет отвечать за переключение на другую личность. Второй - actionStopImpersonating и он отвечает за возвращение к нашей основной личности. Поскольку эти действия касаются конфиденциальной информации и учетных данных, крайне важно установить AccessControl поведение и быть уверенным, что никто, кроме как admin, не сможет переключиться на другую личность.

use app\components\WebUser;
use app\models\User;
use yii\filters\AccessControl;
use yii\web\Controller;

class UserController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'only' => ['impersonate', 'stop-impersonating'],
                'rules' => [
                    [
                        'actions' => ['impersonate', 'stop-impersonating'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function () {
                            return Yii::$app->getUser()->getIsAdmin();
                        }
                    ],
                ],
            ],
        ];
    }


    public function actionImpersonate($id)
    {
        /** @var WebUser $webUser */
        $webUser = Yii::$app->getUser();

        $mainIdentityId = $webUser->getMainIdentityId();

        if ($mainIdentityId != $id) {
            /** @var User $user */
            $user = User::findOne($id);

            $webUser->login($user, $duration = 0);
            $webUser->setMainIdentityId($mainIdentityId);
        }

        return $this->redirect(['/your_route']);
    }

    public function actionStopImpersonating()
    {
        /** @var WebUser $webUser */
        $webUser = Yii::$app->getUser();

        $mainIdentityId = $webUser->getMainIdentityId();

        if (!empty($mainIdentityId)) {
            /** @var User $user */
            $user = User::findOne($mainIdentityId);

            $webUser->login($user, $duration = 0);
            $webUser->setMainIdentityId(null);
        }

        return $this->redirect(['/your_route']);
    }
}

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

Источник: How to do identity impersonation with Yii2.

{{ message }}

{{ 'Comments are closed.' | trans }}