Connexion automatique sur le frontend depuis le backend


15

Voir le scénario suivant.
J'ai un module personnalisé qui permet à l'utilisateur frontal d'effectuer certaines actions sur certaines entités personnalisées. (les détails ne sont pas vraiment importants).
La demande est qu'un administrateur doit pouvoir se connecter sur le frontend avec le compte client (sans avoir le mot de passe) et être capable d'effectuer ces actions pour le client.
Étant donné que vous ne pouvez pas utiliser la session frontend à partir du backend et que je ne veux pas créer de lien d'authentification automatique permanent pour le frontend car cela pourrait être un gros trou de sécurité, c'est ce que j'ai fait jusqu'à présent.

  • ajoutez un attribut vide pour l'entité client. (appelons-le login_key)
  • ajoutez un bouton dans le backend sur la page d'édition du client qui redirige vers une page d' administration où une chaîne aléatoire est générée et enregistrée dans l'attribut login_key.
  • dans la même action, je redirige l'administrateur vers une URL frontend comme celle-ci autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(valeur générée à l'étape précédente).
  • à l'URL frontend, si l'ID client login_keycorrespond à un client spécifique, je mets l'objet client en session (comme connecté) et je le supprime login_keypour que l'URL ne fonctionne plus à l'avenir.

Cela semble fonctionner. Je veux dire, je me connecte en tant que client sélectionné et le lien utilisé pour la connexion automatique ne fonctionne pas une deuxième fois.
L'inconvénient est que si 2 administrateurs cliquent sur le bouton "Autologin" à peu près en même temps, l'un ne parviendra pas à se connecter, mais c'est un risque acceptable.
Ma principale préoccupation est que cela peut également être un (pas que) gros problème de sécurité. Quelqu'un peut-il voir quelque chose de mal avec cette approche? ou suggérer un meilleur?
Ignorez le fait que les comptes clients peuvent être séparés par site Web. Ce n'est pas important et peut également être géré facilement.


Les clés URL d'administration régulières ne vous donneraient-elles pas autant de sécurité?
kalenjordan

@kalenjordan Le problème n'est pas la partie admin. Cela semble OK. Ma préoccupation est lors de l'appel de l'URL frontend pour la connexion automatique. Je ne peux pas utiliser de clés URL d'administration là-dedans.
Marius

Ah oui, désolé. Avez-vous vérifié magentocommerce.com/magento-connect/login-as-customer-9893.html ? Il génère un enregistrement unique par tentative de connexion par l'administrateur, avec un hachage unique associé à l'ID client utilisé dans le contrôleur frontal.
kalenjordan

@kalenjordan Ha Ha. Je ne connaissais pas cette extension. mais d'après ce que vous avez décrit, c'est la même approche que celle que j'ai décrite dans la question. :). Je vais y jeter un œil. Merci.
Marius

1
@ mageUz.True, mais comme je l'ai dit, c'est un risque acceptable. Je suis plus préoccupé par la sécurité ici.
Marius

Réponses:


9

Puisque personne n'a trouvé une bonne raison de ne pas faire ce que je demandais, je suppose que ma méthode est assez sûre. Donc, afin de ne pas laisser cette question ouverte, j'ai décidé d'ajouter le code comme réponse et de le marquer comme accepté.
J'ai donc une nouvelle extension appelée Easylife_Simulateavec les fichiers suivants: app/etc/modules/Easylife_Simulte.xml- le fichier de déclaration:

<?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 - le fichier de configuration

<?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 d'installation - ajoute un nouvel attribut client:

<?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 - observateur pour ajouter un bouton dans le formulaire de modification de l'administrateur client

<?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 - le contrôleur d'administration qui gère le clic sur le bouton généré ci-dessus.

<?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 - le contrôleur frontal qui fait l'autologin.

<?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 - l'aide au module

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

C'est ça. Cela semble fonctionner pour moi. Comme je l'ai dit dans la question, l'inconvénient est que si 2 administrateurs appuient sur le bouton de connexion pour le même client en même temps (environ), l'un d'eux ne sera pas connecté. Mais il peut répéter le processus quelques secondes plus tard.


Que se passe-t-il lorsqu'il y a plusieurs clients?
Milople Inc

@GarthHuff Je ne comprends pas votre question. Veuillez décrire votre scénario.
Marius

Je pense que j'ai changé tout le scénario, ce que j'ai fait est de remplacer la zone de saisie du nom d'utilisateur par une liste déroulante par un nom d'utilisateur possible et de se connecter automatiquement lorsque le nom d'utilisateur est sélectionné dans la liste déroulante. Ceci est mon implémentation techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc

@GarthHuff. Merci pour le script, mais mon problème est lié aux clients frontend, pas aux administrateurs.
Marius

@Marius prévoyez-vous d'en faire une version Magento 2?
Dan

0

Nous utilisons une approche similaire pour notre équipe de service client appelée "connexion fantôme" où nous mettons à disposition un bouton via le compte client dans l'admin. Nous n'utilisons aucun attribut personnalisé pour login_key ou quelque chose comme ça et utilisons en fait une loginAction remplacée / personnalisée étendue à partir de Mage_Customer_AccountController pour traiter la connexion.

De plus, pendant loginAction, après notre logique et validation personnalisées, nous utilisons Mage_Customer_Model_Session :: setCustomerAsLoggedIn pour nous assurer que nous ne perdons aucune fonctionnalité d'événement pouvant être exécutée lors de la connexion. Si vous jetez un œil à cette méthode, vous remarquerez qu'elle définit le client dans la session ainsi que distribue l'événement customer_login.

entrez la description de l'image ici

Avec cette approche, nous pouvons en fait avoir plusieurs agents connectés en tant que même client si nous choisissons (bien que nous ne voulions pas que plusieurs agents ajoutent au panier / passent des commandes en même temps sur le même compte).

Nous l'utilisons depuis deux ans maintenant sans aucun problème notable pendant cette période.


1
Merci pour l'info. J'utilise également setCustomerAsLoggedIndans mon code, pour la même raison que vous. Mais j'étais curieux de la méthode à utiliser pour l'autologin. (si ce n'est pas un secret).
Marius

Nous avons construit un module personnalisé pour gérer cela qui s'étend de la fonctionnalité de connexion frontale de base.
Anthony Leach Jr

J'ai compris. Je posais des questions sur un code, si possible, ou du moins sur l'idée derrière le code. Ou peut-être quelques conseils si mon idée est sûre ou non.
Marius
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.