Autologin am Frontend aus dem Backend

15

Siehe folgendes Szenario.
Ich habe ein benutzerdefiniertes Modul, mit dem der Frontend-Benutzer einige Aktionen für einige benutzerdefinierte Entitäten ausführen kann. (Details sind nicht wirklich wichtig).
Die Anforderung ist, dass sich ein Administrator am Frontend mit dem Kundenkonto anmelden kann (ohne das Passwort zu haben) und diese Aktionen für den Kunden ausführen kann.
Da Sie die Frontend-Sitzung des Backends nicht verwenden können und ich keinen permanenten Autologin-Link für das Frontend erstellen möchte, da dies möglicherweise eine große Sicherheitslücke darstellt, habe ich dies bisher getan.

  • Fügen Sie ein leeres Attribut für die Kundenentität hinzu. (Nennen wir es login_key)
  • Fügen Sie im Backend der Kundenbearbeitungsseite eine Schaltfläche hinzu, die auf eine umleitet Administrationsseite auf der eine zufällige Zeichenfolge generiert und im Attribut gespeichert wird login_key.
  • In der gleichen Aktion leite ich den Administrator auf eine Frontend-URL wie diese um autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(Wert, der im vorherigen Schritt generiert wurde).
  • Wenn die Kunden-ID und die login_keyÜbereinstimmung für einen bestimmten Kunden an der Frontend-URL übereinstimmen, setze ich das Kundenobjekt in der Sitzung (wie angemeldet) und lösche daslogin_key die URL, damit die URL in Zukunft nicht mehr funktioniert.

Das scheint zu funktionieren. Ich werde als der ausgewählte Kunde angemeldet und der für die automatische Anmeldung verwendete Link funktioniert ein zweites Mal nicht.
Die Kehrseite ist, dass wenn 2 Administratoren gleichzeitig auf die Schaltfläche "Autologin" klicken, eine Anmeldung fehlschlägt, dies jedoch ein akzeptables Risiko darstellt.
Mein Hauptanliegen ist, dass dies auch ein (nicht so großes) Sicherheitsproblem sein kann. Kann jemand etwas falsch mit diesem Ansatz sehen? oder einen besseren vorschlagen?
Ignorieren Sie die Tatsache, dass die Kundenkonten nach Website getrennt werden können. Dies ist nicht wichtig und kann auch leicht verwaltet werden.

Marius
quelle
Würden reguläre Admin-URL-Schlüssel Ihnen nicht genauso viel Sicherheit bieten?
Kalenjordan
@kalenjordan Das Problem ist nicht der Admin-Teil. Das scheint in Ordnung zu sein. Ich mache mir Sorgen, wenn ich die Frontend-URL für die automatische Anmeldung aufrufe. Ich kann dort keine Admin-URL-Schlüssel verwenden.
Marius
Ah richtig, sorry. Haben Sie magentocommerce.com/magento-connect/login-as-customer-9893.html ausgecheckt ? Pro Anmeldeversuch generiert der Administrator einen eindeutigen Datensatz mit einem eindeutigen Hash, der der Kunden-ID zugeordnet ist, die im Frontend-Controller verwendet wird.
Kalenjordan
@kalenjordan Ha Ha. Ich wusste nichts über diese Erweiterung. aber von dem, was Sie beschrieben haben, ist der gleiche Ansatz, den ich in der Frage beschrieben habe. :). Ich werde es mir ansehen. Vielen Dank.
Marius
1
@mageUz.True, aber wie gesagt, das ist ein akzeptables Risiko. Hier geht es mir mehr um Sicherheit.
Marius

Antworten:

9

Da mir niemand einen guten Grund einfiel, nicht das zu tun, worum ich gebeten hatte, gehe ich davon aus, dass meine Methode sicher ist. Um diese Frage nicht offen zu lassen, habe ich beschlossen, den Code als Antwort hinzuzufügen und als akzeptiert zu markieren.
Ich habe also eine neue Endung Easylife_Simulatemit den folgenden Dateien: app/etc/modules/Easylife_Simulte.xml- Die Deklarationsdatei:

<?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 - die Konfigurationsdatei

<?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 - install script - fügt ein neues Kundenattribut hinzu:

<?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 - Beobachter, um eine Schaltfläche im Bearbeitungsformular für Kundenadministratoren hinzuzufügen

<?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 - Der Administrator-Controller, der den Klick auf die oben generierte Schaltfläche verarbeitet.

<?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 - der Frontend-Controller, der die automatische Anmeldung vornimmt.

<?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 - der Modulhelfer

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Das ist es. Es scheint, für mich zu arbeiten. Wie ich in der Frage sagte, besteht der Nachteil darin, dass, wenn zwei Administratoren (ungefähr) gleichzeitig auf den Anmeldebutton desselben Kunden drücken, einer von ihnen nicht angemeldet ist. Er kann den Vorgang jedoch einige Sekunden später wiederholen.

Marius
quelle
Was passiert, wenn es mehrere Kunden gibt?
Milople Inc
@GarthHuff Ich verstehe deine Frage nicht. Bitte beschreiben Sie Ihr Szenario.
Marius
Ich denke, ich habe das gesamte Szenario geändert. Ich habe Folgendes getan: Ersetze das Eingabefeld für den Benutzernamen mit dem Dropdown-Menü mit dem möglichen Benutzernamen und melde mich automatisch an, wenn der Benutzername aus dem Dropdown-Menü ausgewählt wird. Dies ist meine Implementierung techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc
@GarthHuff. Vielen Dank für das Skript, aber mein Problem betrifft Frontend-Kunden, nicht Administratoren.
Marius
@Marius hast du vor, eine Magento 2-Version davon zu machen?
Dan
0

Wir verwenden einen ähnlichen Ansatz für unser Kundenserviceteam mit dem Namen "Ghost Login", bei dem wir einen Button über das Kundenkonto in admin verfügbar machen. Wir verwenden keine benutzerdefinierten Attribute für login_key oder ähnliches und verwenden tatsächlich eine überschriebene / angepasste loginAction, die von Mage_Customer_AccountController erweitert wurde, um die Anmeldung zu verarbeiten.

Darüber hinaus verwenden wir während loginAction nach unserer benutzerdefinierten Logik und Überprüfung Mage_Customer_Model_Session :: setCustomerAsLoggedIn, um sicherzustellen, dass wir keine Ereignisfunktionalität verlieren, die möglicherweise während der Anmeldung ausgeführt wird. Wenn Sie sich diese Methode ansehen, werden Sie feststellen, dass sie den Kunden in die Sitzung versetzt und das customer_login -Ereignis auslöst.

Bildbeschreibung hier eingeben

Mit diesem Ansatz können sich tatsächlich mehrere Agenten als derselbe Kunde anmelden, den wir wählen sollten (obwohl wir nicht möchten, dass mehrere Agenten gleichzeitig Bestellungen auf demselben Konto auf den Warenkorb legen).

Wir verwenden dies seit zwei Jahren ohne nennenswerte Probleme in dieser Zeit.

Anthony Leach Jr
quelle
1
Danke für die Information. Ich benutze auch setCustomerAsLoggedInin meinem Code, aus dem gleichen Grund wie Sie. Aber ich war neugierig auf die Methode für die automatische Anmeldung. (wenn es kein Geheimnis ist).
Marius
Wir haben ein benutzerdefiniertes Modul erstellt, um dies zu handhaben, das sich von der zentralen Frontend-Anmeldefunktion erstreckt.
Anthony Leach Jr
Ich habe das verstanden. Ich habe nach einem Code gefragt, wenn möglich, oder zumindest nach der Idee, die hinter dem Code steckt. Oder vielleicht ein paar Hinweise, ob meine Idee sicher ist oder nicht.
Marius