I have developed this solution for some of my web apps and works flawless. Let's start by assuming some facts:
- You save user's passwords hashed in your DB
- A user needs to enter his email and password to log in.
I developed an AdminController from which I can see every user in a list, and inside that controller there is an action call "loginasAction" which receives a parameter from the URL (read the code below):
public function loginasAction() {
$params = $this->params()->fromQuery();
//this is the email of the user we want to log in as
$user=$params['loginas'];
//the current session data
$userSession = new Container('appData');
//a new session container built for the ocassion
$adminSession = new Container('adminData');
//save your admin user session as "originalUser" in the new session container,
//because the original one is going to be cleared
$adminSession->originalUser = $userSession->user;
//retrieve the user data and asave it into the new session container too
$userModel = new UserModel();
$user= $userModel->getUser($user);
$adminSession->clientAdmin = $clientAdmin;
//redirect to my LogController Login action.
return $this->redirect()->toRoute('login', array(), array('query' => array('loginas' => '')));
}
Let's see what we have at Login action:
//check if it comes form admin panel
$params = $this->params()->fromQuery();
if (isset($params['loginas'])) {
$adminSession = new Container('adminData');
if (isset($adminSession->userToLog)) {
//let's use the destination user to log in as
$user = $adminSession->userToLog;
unset($adminSession->userToLog);
//clear previous user session
$session = new Container('appData');
$session->getManager()->getStorage()->clear('appData');
//log new user and redirect
//userSession is a function that save the user data
//in my appData container session in the way I need it
$this->userSession($user);
//since I have loged in the user, we can redirect ourselves to home page
return $this->redirect()->toRoute('home');
}
}
Right now we have appData container session with the loged in user and adminData container session with our "admin user", the one we use.
How do we go back to our admin user?
My login action can read a parameter from URL called "loguotas", in that case we will check if there is an admin session saved in adminData session container. In that case we will clear the current appData session and save there the adminData user we saved at the beginning of the process, which is our admin user.
//check if it is an admin user that want to return to view clients list
if (isset($params['logoutas'])) {
$adminSession = new Container('adminData');
if (isset($adminSession->originalUser)) {
$originalUser = $adminSession->originalUser;
//clean sessions
$session = new Container('appData');
$session->getManager()->getStorage()->clear();
//log in original user and redirect
$this->userSession($originalUser);
return $this->redirect()->toRoute('admin');
}
}
It is no easy nor too complex, but you need to sit down and think about it for a few minutes. I hope this servers you well, or at least gives you a starting point for your web app.