Inicio de sesión automático en la interfaz desde el backend

15

Vea el siguiente escenario.
Tengo un módulo personalizado que permite al usuario frontend realizar algunas acciones en algunas entidades personalizadas. (Los detalles no son realmente importantes).
La solicitud es que un administrador pueda iniciar sesión en la interfaz con la cuenta del cliente (sin tener la contraseña) y poder realizar esas acciones para el cliente.
Dado que no puede usar la sesión de interfaz desde el backend y no quiero crear un enlace de inicio de sesión permanente para frontend ya que podría ser un gran agujero de seguridad, esto es lo que hice hasta ahora.

  • agregue un atributo vacío para la entidad del cliente. (vamos a llamarlo login_key)
  • agregue un botón en el backend en la página de edición del cliente que redirige a una página de administración donde se genera una cadena aleatoria y se guarda en el atributo login_key.
  • En la misma acción, redirijo al administrador a una URL de interfaz como esta autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(valor generado en el paso anterior).
  • en la URL de la interfaz, si la identificación del cliente y la login_keycoincidencia para un cliente específico, configuro el objeto del cliente en la sesión (como conectado) y elimino login_keyla URL para que la URL no funcione en el futuro.

Esto parece funcionar. Es decir, me conecto como el cliente seleccionado y el enlace utilizado para el inicio de sesión automático no funciona por segunda vez.
La desventaja es que si 2 administradores hacen clic en el botón "autologin" al mismo tiempo, uno no podrá iniciar sesión, pero este es un riesgo aceptable.
Mi principal preocupación es que esto también puede ser un (no ese) gran problema de seguridad. ¿Alguien puede ver algo mal con este enfoque? o sugerir una mejor?
Ignore el hecho de que las cuentas de los clientes pueden estar separadas por el sitio web. Esto no es importante y también se puede gestionar fácilmente.

Marius
fuente
¿Las claves regulares de URL de administrador no le darían tanta seguridad?
kalenjordan
@kalenjordan El problema no es la parte administrativa. Eso parece bien. Mi preocupación es cuando llamo a la URL de la interfaz para iniciar sesión automáticamente. No puedo usar claves de URL de administrador allí.
Marius
Ah cierto, lo siento. ¿Has echado un vistazo a magentocommerce.com/magento-connect/login-as-customer-9893.html ? Genera un registro único por intento de inicio de sesión por parte del administrador, con un hash único asociado a la ID del cliente que se utiliza en el controlador de interfaz.
kalenjordan
@kalenjordan Ja Ja. No sabía sobre esa extensión. pero por lo que describiste es el mismo enfoque que describí en la pregunta. :). Le echaré un vistazo. Gracias.
Marius
1
@ mageUz.True, pero como dije, ese es un riesgo aceptable. Estoy más preocupado por la seguridad aquí.
Marius

Respuestas:

9

Como a nadie se le ocurrió una buena razón para no hacer lo que le estaba pidiendo, asumo que mi método es seguro. Entonces, para no dejar esta pregunta abierta, decidí agregar el código como respuesta y marcarlo como aceptado.
Entonces tengo una nueva extensión llamada Easylife_Simulatecon los siguientes archivos: app/etc/modules/Easylife_Simulte.xml- el archivo de declaración:

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Simulate>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Customer />
            </depends>
        </Easylife_Simulate>
    </modules>
</config>

app/code/local/Easylife/Simulte/etc/config.xml - el archivo de configuración

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Simulate>
            <version>0.0.1</version>
        </Easylife_Simulate>
    </modules>
    <global>
        <helpers>
            <easylife_simulate>
                <class>Easylife_Simulate_Helper</class>
            </easylife_simulate>
        </helpers>
        <models>
            <easylife_simulate>
                <class>Easylife_Simulate_Model</class>
            </easylife_simulate>
        </models>
        <resources>
            <easylife_simulate_setup>
                <setup>
                    <module>Easylife_Simulate</module>
                    <class>Mage_Customer_Model_Resource_Setup</class>
                </setup>
            </easylife_simulate_setup>
        </resources>
    </global>
    <frontend>
        <routers>
            <easylife_simulate>
                <use>standard</use>
                <args>
                    <module>Easylife_Simulate</module>
                    <frontName>simulate</frontName>
                </args>
            </easylife_simulate>
        </routers>
    </frontend>
    <adminhtml>
        <events>
            <controller_action_layout_render_before_adminhtml_customer_edit>
                <observers>
                    <easylife_simulate>
                        <class>easylife_simulate/observer</class>
                        <method>addAutoLoginButton</method>
                    </easylife_simulate>
                </observers>
            </controller_action_layout_render_before_adminhtml_customer_edit>
        </events>
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <Easylife_Simulate before="Mage_Adminhtml">Easylife_Simulate_Adminhtml</Easylife_Simulate>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

app/code/local/Easylife/Simulate/sql/easylife_simulate_setup/install-0.0.1.php - instalar script: agrega un nuevo atributo de cliente:

<?php
$this->addAttribute('customer', 'login_key', array(
    'type'      => 'text',
    'label'     => 'Auto login key',
    'input'     => 'text',
    'position'  => 999,
    'required'  => false
));

app/code/local/Easylife/Simulate/Model/Observer.php - observador para agregar un botón en el formulario de edición de administración del cliente

<?php
class Easylife_Simulate_Model_Observer extends Mage_ProductAlert_Model_Observer{
    public function addAutoLoginButton($observer){
        $block = Mage::app()->getLayout()->getBlock('customer_edit');
        if ($block){
            $customer = Mage::registry('current_customer');
            $block->addButton('login', array(
                'label'     => Mage::helper('customer')->__('Login as this customer'),
                'onclick'   => 'window.open(\''.Mage::helper('adminhtml')->getUrl('adminhtml/simulate/login', array('id'=>$customer->getId())).'\')',
            ), 100);
        }

    }
}

app/code/local/Easylife/Simulate/controllers/Adminhtml/SimulateController.php - el controlador de administrador que maneja el clic en el botón generado anteriormente.

<?php
class Easylife_Simulate_Adminhtml_SimulateController extends Mage_Adminhtml_Controller_Action{
    public function loginAction(){
        $id = $this->getRequest()->getParam('id');
        $customer = Mage::getModel('customer/customer')->load($id);
        if (!$customer->getId()){
            Mage::getSingleton('adminhtml/session')->addError(Mage::helper('easylife_simulate')->__('Customer does not exist'));
            $this->_redirectReferer();
        }
        else {
            $key = Mage::helper('core')->uniqHash();
            $customer->setLoginKey($key)->save();
            $this->_redirect('simulate/index/index', array('id'=>$customer->getId(), 'login_key'=>$key));
        }
    }
}

app/code/local/Easylife/Simulate/controllers/IndexController.php - El controlador frontend que hace el inicio de sesión automático.

<?php
class Easylife_Simulate_IndexController extends Mage_Core_Controller_Front_Action{
    public function indexAction(){
        $id = $this->getRequest()->getParam('id');
        $key = $this->getRequest()->getParam('login_key');
        if (empty($key)){
            $this->_redirect('');
        }
        else{
            $customer = Mage::getModel('customer/customer')->load($id);
            if ($customer->getId() && $customer->getLoginKey() == $key){
                $customer->setLoginKey('')->save();
                Mage::getSingleton('customer/session')->setCustomerAsLoggedIn($customer);
                Mage::getSingleton('customer/session')->renewSession();
            }
            $this->_redirect('customer/account/index');
        }
    }
}

app/code/local/Easylife/Simulte/Helper/Data.php - el ayudante del módulo

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Eso es. Parece que funciona para mí. Como dije en la pregunta, la desventaja es que si 2 administradores presionan el botón de inicio de sesión para el mismo cliente aproximadamente (al mismo tiempo), uno de ellos no se registrará. Pero puede repetir el proceso unos segundos más tarde.

Marius
fuente
¿Qué sucede cuando hay varios clientes?
Milople Inc
@GarthHuff No entiendo tu pregunta. Por favor describa su escenario.
Marius
Creo que he cambiado todo el escenario, lo que he hecho es reemplazar el cuadro de entrada del nombre de usuario con un menú desplegable con un posible nombre de usuario e iniciar sesión automáticamente cuando se selecciona el nombre de usuario del menú desplegable. Esta es mi implicación techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc
@GarthHuff. Gracias por el script, pero mi problema está relacionado con los clientes frontend, no con los administradores.
Marius
@ Mario, ¿planeas hacer una versión de Magento 2 de esto?
Dan
0

Utilizamos un enfoque similar para nuestro equipo de servicio al cliente llamado "inicio de sesión fantasma", donde ponemos a disposición un botón a través de la cuenta del cliente en admin. No estamos utilizando ningún atributo personalizado para login_key ni nada por el estilo y en realidad estamos utilizando una loginAction anulada / personalizada extendida desde Mage_Customer_AccountController para procesar el inicio de sesión.

Además, durante loginAction, después de nuestra lógica y validación personalizadas, estamos utilizando Mage_Customer_Model_Session :: setCustomerAsLoggedIn para garantizar que no perdamos ninguna funcionalidad de evento que pueda ejecutarse durante el inicio de sesión. Si observa este método, notará que establece al cliente en la sesión y envía el evento customer_login.

ingrese la descripción de la imagen aquí

Con este enfoque, podemos hacer que varios agentes inicien sesión como el mismo cliente si así lo decidiéramos (aunque no quisiéramos que múltiples agentes agreguen al carrito / realicen pedidos al mismo tiempo en la misma cuenta).

Hemos estado usando esto durante dos años sin problemas notables durante ese tiempo.

Anthony Leach Jr
fuente
1
Gracias por la info. También lo uso setCustomerAsLoggedInen mi código, por la misma razón que tú. Pero tenía curiosidad sobre el método a utilizar para el inicio de sesión automático. (Si no es un secreto).
Marius
Hemos creado un módulo personalizado para manejar esto que se extiende desde la funcionalidad de inicio de sesión principal de la interfaz de usuario.
Anthony Leach Jr
Lo tengo. Estaba preguntando acerca de algún código, si es posible, o al menos la idea detrás del código. O tal vez algunos consejos si mi idea es segura o no.
Marius