CakePHP 4 - Impersonate Another User

CakePHP 4 - Impersonate Another User

This article demonstrates how to login as another user by impersonation, in CakePHP4.  This allows administrators to login as another user and test issues with that user.

Note that Authentication version 2.10.0 has an impersonation function.  This solution can be used with Authentication version 2.0, which doesn't support impersonation.

First, make sure your Authentication component is loaded - usually in the AppController/initialize().

$this->loadComponent('Authentication.Authentication');

 

Next, create a function (UsersController.php in this case), get the specified user, and use Authentication->setIdentity for that user as shown below:

public function impersonateStart($newUserId) {

    $originalUser = $this->Authentication->getIdentity();

    $user = $this->Users->find('all', array(
        'conditions' => array(
            'users.id' => $newUserId
        )
    ))->first();

    if ($user) {
        $this->Authentication->logout();  //log user out first
        $this->getRequest()->getSession()->write('Impersonate', $originalUser);
        $this->Authentication->setIdentity($user);
        $this->Flash->success(__('You are now logged in as ' . $user['username']));

        return $this->redirect('/');

    } else {
        $this->Flash->error(__('Invalid user id'));
        return;
    }
}

 

Next, you can use the following function to stop the impersonation.

public function impersonateStop() {

    $userId = $this->getRequest()->getSession()->read('Impersonate')->id;
    $user = $this->Users->get($userId);

    // log out the impersonated user
    $this->Authentication->logout();

    // log in the original user
    $this->Authentication->setIdentity($user);

    // destroy the impersonated user's session
    $this->getRequest()->getSession()->delete('Impersonate');

    // redirect the user back to their own session
    return $this->redirect('/admin/users/');
}

 

Lastly, you can check if user is being impersonated with this snipplet:

//check for Impersonate
$session = $this->getRequest()->getSession();
$origImpersonatorId = null;
if( !is_null($session->read('impersonate'))) {
    $origImpersonatorId = $session->read('impersonate')->id;
    $this->set('origImpersonatorId ', $origImpersinatorId);
    $this->Flash->info(__('You are currently impersonating another user.'));
}

 

Then, in a view, for example, you could check for the $origImpersonatorId

if(!is_null($origImpersinatorId)) {
     echo '<a href="/admin/Users/impersonateStop/">Stop Impersonating</a>';
}

Share this Post