Login as Customer – Magento extension

One possibly cool feature that Magento is missing is the ability for admin user to login as customer. Why is this needed? Well, honestly I dont see a reason why such feature would be required since admin users can change customer info from the admin area and can create orders for customers from admin area. One possible reason can be for more precise debugging of issues customers report with their customer accounts, etc. Nevertheless, lets see how we can make such functionality.
First, lets see what’s the challenge with creating such functionality? We all know Magento supports multi-websites functionality, right? Now take the System > Configuration > Customers > Customer Configuration > Account Sharing Options > Share Customer Accounts option into consideration. This option can be set to either Global or Per Website value.
If the Share Customer Accounts option is set to Global that means that customer can log into any existing website powered by running Magento instance. On the other hand if Share Customer Accounts option is set to Per Website that means that customer can log only into website(s) he registered (signed up) in. To keep things functioning the right way we have to stick to this simple rule.
You can easily check if Share Customer Accounts option is set to Per Website via this line of code
Mage::getSingleton('customer/config_share')->isWebsiteScope()
and if its not Per Website then its Global.
Now that we got that simple check code snippet, lets move on. The way we will implement the functionality is to add the Login as Customer button on the customer edit screen. There are several ways to add the button on that screen. Usually, developer just rewrites the block that renders the screen and adds the functionality through it. I however like to squeeze the event functionality as much as I can so here is an example how to add a button to customer edit screen via event/observer approach. The event we are interested is adminhtml_widget_container_html_before, triggered under adminhtml.
app/code/community/Inchoo/LoginAsCustomer/etc/config.xml
<adminhtml>
<events>
<adminhtml_widget_container_html_before>
<observers>
<inchoo_loginAsCustomer_injectLoginAsCustomerButton>
<class>inchoo_loginAsCustomer/observer</class>
<method>injectLoginAsCustomerButton</method>
</inchoo_loginAsCustomer_injectLoginAsCustomerButton>
</observers>
</adminhtml_widget_container_html_before>
</events>
</adminhtml>
And the implementation of injectLoginAsCustomerButton method as shown below:
class Inchoo_LoginAsCustomer_Model_Observer
{
public function injectLoginAsCustomerButton($observer)
{
$block = $observer->getEvent()->getBlock();
if ($block instanceof Mage_Adminhtml_Block_Customer_Edit) {
if ($this->getCustomer() && $this->getCustomer()->getId()) {
$block->addButton('loginAsCustomer', array(
'label' => Mage::helper('customer')->__('Login as Customer'),
'onclick' => 'setLocation(\'' . $this->getLoginAsCustomerUrl() . '\')',
'class' => 'loginAsCustomer',
), 0);
}
}
}
public function getCustomer()
{
return Mage::registry('current_customer');
}
public function getLoginAsCustomerUrl()
{
/*
If option "System > Configuration > Customers > Customer Configuration > Account Sharing Options > Share Customer Accounts"
is set to "Per Website" value. What this means is that this account is tied to single website.
*/
if (Mage::getSingleton('customer/config_share')->isWebsiteScope()) {
return Mage::helper('adminhtml')->getUrl('*/inchoo_LoginAsCustomer/login', array(
'customer_id' => $this->getCustomer()->getId(),
'website_id' => $this->getCustomer()->getWebsiteId(),
));
}
/* else, this means we have "Global", so customer can login to any website, so we show him the list of websites */
return Mage::helper('adminhtml')->getUrl('*/inchoo_LoginAsCustomer/index', array('customer_id' => $this->getCustomer()->getId()));
}
}
Next, we will define two controllers Inchoo_LoginAsCustomer_Adminhtml_Inchoo_LoginAsCustomerController and Inchoo_LoginAsCustomer_CustomerController. Reason for that is that we will do some juggling between two.
/app/code/community/Inchoo/LoginAsCustomer/controllers/Adminhtml/Inchoo/LoginAsCustomerController.php:
class Inchoo_LoginAsCustomer_Adminhtml_Inchoo_LoginAsCustomerController extends Mage_Adminhtml_Controller_Action
{
public function indexAction()
{
$this->loadLayout()->_setActiveMenu('sales/inchoo_loginAsCustomer');
$this->_addContent($this->getLayout()->createBlock('inchoo_loginAsCustomer/adminhtml_edit'));
$this->renderLayout();
}
public function gridAction()
{
$this->getResponse()->setBody(
$this->getLayout()->createBlock('inchoo_loginAsCustomer/adminhtml_edit_grid')->toHtml()
);
}
public function loginAction()
{
$info = Mage::helper('core')->encrypt(serialize(array(
'website_id' => $this->getRequest()->getParam('website_id'),
'customer_id' => $this->getRequest()->getParam('customer_id'),
'timestamp' => time(),
)));
$this->_redirectUrl(Mage::app()->getWebsite($this->getRequest()->getParam('website_id'))->getConfig('web/unsecure/base_url').'index.php/inchoo_loginAsCustomer/customer/login?loginAsCustomer='.base64_encode($info));
}
}
/app/code/community/Inchoo/LoginAsCustomer/controllers/CustomerController.php:
class Inchoo_LoginAsCustomer_CustomerController extends Mage_Core_Controller_Front_Action
{
public function loginAction()
{
/* parse the 'loginAsCustomer' param */
$info = unserialize(
Mage::helper('core')->decrypt( /* important step; use Magento encryption key to decrypt/extract info */
base64_decode(
$this->getRequest()->getParam('loginAsCustomer')
)
)
);
/* Check to be sure that all 'website_id' & 'customer_id' & 'timestamp' info is passed */
if (isset($info['website_id'])
&& isset($info['customer_id'])
&& isset($info['timestamp'])
&& (time() < ($info['timestamp'] + 5))) { /* 5 second validity for request */
$customerSession = Mage::getSingleton('customer/session');
/* Share Customer Accounts is set to "Per Website" */
if (Mage::getSingleton('customer/config_share')->isWebsiteScope()) {
if (Mage::app()->getWebsite()->getId() != $info['website_id']) {
Mage::getSingleton('customer/session')->addNotice($this->__('<i>Share Customer Accounts</i> option is set to <i>Per Website</i>. You are trying to login as customer from website %d into website %s. This action is not allowed.', $info['website_id'], Mage::app()->getWebsite()->getId()));
$this->_redirect('customer/account');
return;
}
}
/* Logout any currently logged in customer */
if ($customerSession->isLoggedIn()) {
$customerSession->logout();
}
/* Login new customer as requested on the admin interface */
$customerSession->loginById($info['customer_id']);
}
$this->_redirect('customer/account');
}
}
In order to login the customer we need to execute the following line of code:
Mage::getSingleton('customer/session')->loginById( SOME_CUSTOMER_ID_HERE );
However, executing this code from the admin area wont do a thing. You need to execute it from frontend area, thus the frontend controller. In order to keep things safe we will use our admin controller to encrypt the data about the customer we want to login and send that data to frontend controller. Once triggered, frontend controller will try to decrypt the data passed to it, and if successful it will log in the proper customer.
Keeping the multi-website functionality in mind, admin controller wil also read the proper website base url config option, which you can see is done via following line of code:
Mage::app()->getWebsite( SOME_WEBSITE_ID )->getConfig('web/unsecure/base_url')
Overall, thats it. You can find the full source code for the Inchoo_LoginAsCustomer extension here.
9 comments
He has no Permission Rules. And it does not appear for users who do not have full permission.
How can I solve this?
If you are looking for a solution which has Admin Permissions to use Login As Customer feature, then you can try PotatoCommerce Login As Customer extension.
I do accept as true with all of the ideas you’ve introduced in your
post. They are really convincing and can certainly work.
Still, the posts are too short for beginners.
May you please extend them a bit from next time?
Thank you for the post.
Hi,
This module is great but after enabling redis db session cache the module stops doing what it should do and only redirects to login page on front-end.
Is there an easy way to fix this?
Kind regards Bobby
what role resource permission that i must activate to use this extension? thanks before
thanks a lot.. !!
Works perfect with CE 1.7.0.2 and is very helpful, even for some admin tasks as a dealer.
Thanks
Very usefu, just implemented it!
Note: I had to avoid the “Logout any currently logged in customer” otherwise the logout took precedence over the following login.
Thnk you for sharing!
So, I thought this was a great idea. Untill I ran it and now my website is jacked. Not sure, but it seems like some code got scrambled up. I uninstalled it and no change. Any Ideas?