Login automático no front-end a partir do back-end

15

Veja o seguinte cenário.
Eu tenho algum módulo personalizado que permite ao usuário front-end executar algumas ações em algumas entidades personalizadas. (os detalhes não são realmente importantes).
A solicitação é de que um administrador possa efetuar login no front-end com a conta do cliente (sem ter a senha) e poder executar essas ações para o cliente.
Como você não pode usar a sessão de front-end do back-end e não quero criar um link permanente de logon automático para o front-end, pois pode haver um grande problema de segurança, foi o que fiz até agora.

  • adicione um atributo vazio para a entidade do cliente. (vamos chamá-lo login_key)
  • adicione um botão no back-end na página de edição do cliente que redireciona para uma página de administrador em que uma sequência aleatória é gerada e salva no atributo login_key.
  • na mesma ação, redireciono o administrador para um URL de front-end como este autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(valor gerado na etapa anterior).
  • no URL do front-end, se o ID do cliente login_keycorresponder a um cliente específico, defino o objeto do cliente na sessão (como conectado) e excluo o login_keypara que o URL não funcione no futuro.

Isso parece funcionar. Quero dizer, eu entrei como cliente selecionado e o link usado para o logon automático não funciona uma segunda vez.
O lado negativo é que, se 2 administradores clicarem no botão "login automático" ao mesmo tempo, um falhará no login, mas este é um risco aceitável.
Minha principal preocupação é que esse também possa ser um grande problema de segurança. Alguém pode ver algo errado com essa abordagem? ou sugerir um melhor?
Ignore o fato de que as contas dos clientes podem ser separadas por site. Isso não é importante e também pode ser gerenciado facilmente.

Marius
fonte
As chaves de URL de administrador regulares não oferecem a mesma segurança?
kalenjordan
@kalenjordan O problema não é a parte do administrador. Isso parece bom. Minha preocupação é ao chamar o URL do front-end para login automático. Não consigo usar chaves de URL de administrador lá.
Marius
Ah certo, desculpe. Você já conferiu magentocommerce.com/magento-connect/login-as-customer-9893.html ? Ele gera um registro único por tentativa de login pelo administrador, com um hash exclusivo associado ao ID do cliente que é usado no controlador de front-end.
precisa saber é o seguinte
@kalenjordan Ha Ha. Eu não sabia sobre essa extensão. mas pelo que você descreveu é a mesma abordagem que descrevi na pergunta. :). Vou dar uma olhada nisso. Obrigado.
Marius
1
@ mageUz.True, mas como eu disse, esse é um risco aceitável. Estou mais preocupado com segurança aqui.
Marius

Respostas:

9

Como ninguém apresentou uma boa razão para não fazer o que eu estava pedindo, presumo que meu método seja meio seguro. Portanto, para não deixar essa pergunta em aberto, decidi adicionar o código como resposta e marcá-lo como aceito.
Então, eu tenho uma nova extensão chamada Easylife_Simulatecom os seguintes arquivos: app/etc/modules/Easylife_Simulte.xml- o arquivo de declaração:

<?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 - o arquivo de configuração

<?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 - script de instalação - adiciona um novo 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 adicionar um botão no formulário de edição do administrador do 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 - o controlador administrativo que lida com o clique no botão gerado acima.

<?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 - o controlador front-end que faz o logon 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 - o auxiliar do módulo

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

É isso aí. Parece trabalhar para mim. Como eu disse na pergunta, a desvantagem é que, se 2 administradores pressionarem o botão de login do mesmo cliente (aproximadamente) ao mesmo tempo, um deles não será logado. Mas ele pode repetir o processo alguns segundos depois.

Marius
fonte
O que acontece quando há vários clientes?
Milople Inc
@GarthHuff Não entendi sua pergunta. Por favor, descreva seu cenário.
Marius
Eu acho que mudei todo o cenário. O que fiz foi Substituir a caixa de entrada de nome de usuário pelo menu suspenso por um possível nome de usuário e efetue login automaticamente quando o nome de usuário selecionado no menu suspenso. Esta é minha implementação techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc
@GarthHuff. Obrigado pelo script, mas meu problema está relacionado a clientes de front-end, não a administradores.
Marius
@ Marius você planeja fazer uma versão Magento 2 disso?
Dan
0

Usamos uma abordagem semelhante para nossa equipe de atendimento ao cliente chamada "login fantasma", onde disponibilizamos um botão via conta de cliente em admin. Não estamos usando nenhum atributo personalizado para login_key ou algo parecido e, na verdade, estamos usando uma ação de login substituída / personalizada estendida de Mage_Customer_AccountController para processar o login.

Além disso, durante o loginAction, após nossa lógica e validação personalizadas, estamos usando Mage_Customer_Model_Session :: setCustomerAsLoggedIn para garantir que não estamos perdendo nenhuma funcionalidade de evento que possa ser executada durante o login. Se você der uma olhada nesse método, notará que ele define o cliente na sessão e despacha o evento customer_login.

insira a descrição da imagem aqui

Com essa abordagem, podemos realmente fazer com que vários agentes façam login como o mesmo cliente que devemos escolher (embora não desejemos que vários agentes sejam adicionados ao carrinho / fazendo pedidos ao mesmo tempo na mesma conta).

Estamos usando isso há dois anos, sem problemas notáveis ​​durante esse período.

Anthony Leach Jr
fonte
1
Obrigado pela informação. Eu também uso setCustomerAsLoggedInno meu código, pelo mesmo motivo que você. Mas eu estava curioso sobre o método a ser usado para o login automático. (se não é um segredo).
Marius
Criamos um módulo personalizado para lidar com isso, que se estende da funcionalidade principal de login do front-end.
Anthony Leach Jr
Eu entendi. Eu estava perguntando sobre algum código, se possível, ou pelo menos a idéia por trás do código. Ou talvez algumas dicas, se minha ideia é segura ou não.
Marius