Blog
DEV TIPS & TRICKS

How to Do Identity Impersonation with Yii2

July 9, 2019
6 min read
How to Do Identity Impersonation with Yii2 - Featured Image
By
Srdjan Drakul

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

Don't miss out on
our latest insights
– Subscribe Now!

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Share This Post
Back to Blog
Don't miss out on
our latest insights
– Subscribe Now!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Navigate
Start Now