To begin this process, a basic user component configuration needs to be added inside components with its identityClass
configured such as follows:
1return [
2 'components' => [
3 'user' => [
4 'identityClass' => common\models\User',
5 ]
6 ]
7];
Let's say you are logged into an application as an administrator but your goal is to impersonate another user. This can be really useful when you want to experience how an application looks and feels when viewed by another user.
For easier handling with the user component, we will override the default application user class and place some useful methods inside. Let's name it WebUser
in order to avoid confusion between Active Record user and Application user.
1namespace common\components;
2
3use Yii;
4use yii\web\User;
5
6class WebUser extends User
7{
8 const IDENTITY_ID_KEY = 'mainIdentityId';
9 const ADMIN_PERMISSION = 'admin';
10
11 public function getIsImpersonated()
12 {
13 return !is_null(Yii::$app->session->get(self::IDENTITY_ID_KEY));
14 }
15
16 public function setMainIdentityId($userId)
17 {
18 Yii::$app->sesion->set(self::IDENTITY_ID_KEY, $userId);
19 }
20
21 public function getMainIdentityId()
22 {
23 $mainIdentityId = Yii::$app->session->get(self::IDENTITY_ID_KEY);
24 return !empty($mainIdentityId) ? $mainIdentityId : $this->getId();
25 }
26
27 public function getIsAdmin()
28 {
29 return !$this->getIsGuest() && $this->can(self::ADMIN_PERMISSION);
30 }
31}
32
User components needs to be updated with this configuration:
1return [
2 'components' => [
3 'user' => [
4 'class' => 'common\components\WebUser'
5 'identityClass' => common\models\User',
6 ]
7 ]
8];
9
In order to get this done, we will have to create two separate actions inside our UserController
. The first action is called actionImpersonate
and it will be responsible for switching to another identity. The second one is actionStopImpersonating
and it is responsible for returning back to our main identity. Since these actions are dealing with sensitive information and credentials, it is crucial to set AccessControl
behavior and be certain that nobody except the admin
will be able to switch to another identity.
1use common\components\WebUser;
2use common\models\User;
3use yii\filters\AccessControl;
4use yii\web\Controller;
5
6class UserController extends Controller
7{
8 public function behaviors()
9 {
10 return [
11 'access' => [
12 'class' => AccessControl::class,
13 'only' => ['impersonate', 'stop-impersonating'],
14 'rules' => [
15 [
16 'actions' => ['impersonate', 'stop-impersonating'],
17 'allow' => true,
18 'roles' => ['@'],
19 'matchCallback' => function () {
20 return Yii::$app->getUser()->getIsAdmin();
21 }
22 ],
23 ],
24 ],
25 ];
26 }
27
28
29 public function actionImpersonate($id)
30 {
31 /** @var WebUser $webUser */
32 $webUser = Yii::$app->getUser();
33
34 $mainIdentityId = $webUser->getMainIdentityId();
35
36 if ($mainIdentityId != $id) {
37 /** @var User $user */
38 $user = User::findOne($id);
39
40 $webUser->login($user, $duration = 0);
41 $webUser->setMainIdentityId($mainIdentityId);
42 }
43
44 return $this->redirect(['/land/user/to/route']);
45 }
46
47 public function actionStopImpersonating()
48 {
49 /** @var WebUser $webUser */
50 $webUser = Yii::$app->getUser();
51
52 $mainIdentityId = $webUser->getMainIdentityId();
53
54 if (!empty($mainIdentityId)) {
55 /** @var User $user */
56 $user = User::findOne($mainIdentityId);
57
58 $webUser->login($user, $duration = 0);
59 $webUser->setMainIdentityId(null);
60 }
61
62 return $this->redirect(['/land/user/to/route']);
63 }
64}
When impersonation is done successfully, we can expect to see different data or a different presentation. All the data will be scoped for that user (if data scoping exists) along with permissions that that specific user has. Usually, impersonation is useful when an administrator of the system needs to check a regular user’s panel, whether for support, debugging, or simply in order to make sure the application is used correctly.
Accelerate Your Career with 2am.tech
Join our team and collaborate with top tech professionals on cutting-edge projects, shaping the future of software development with your creativity and expertise.
Open Positions