Autologin na interfejsie z backendu


15

Zobacz następujący scenariusz.
Mam niestandardowy moduł, który pozwala użytkownikowi frontendowi wykonywać pewne działania na niektórych niestandardowych obiektach. (szczegóły nie są tak naprawdę ważne).
Żądanie polega na tym, że administrator powinien mieć możliwość zalogowania się do interfejsu użytkownika za pomocą konta klienta (bez hasła) i wykonania tych czynności dla klienta.
Ponieważ nie możesz użyć sesji frontendowej z backendu i nie chcę tworzyć stałego linku autologin dla frontendu, ponieważ może to być duża dziura w zabezpieczeniach, to właśnie zrobiłem do tej pory.

  • dodaj pusty atrybut dla jednostki klienta. (nazwijmy to login_key)
  • dodaj przycisk w zapleczu na stronie edycji klienta, który przekierowuje na stronę administratora, na której generowany jest losowy ciąg znaków i zapisywany w atrybucie login_key.
  • w tej samej akcji przekierowuję administratora do adresu URL frontonu takiego jak ten autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(wartość wygenerowana w poprzednim kroku).
  • na adresie frontend, jeśli identyfikator klienta i login_keydopasowanie do konkretnego klienta, to ustawiam obiekt klienta w sesji (po zalogowaniu) i usuwam, login_keyaby adres URL nie działał w przyszłości.

To szwy do pracy. Mam na myśli, że loguję się jako wybrany klient, a link użyty do automatycznego logowania nie działa po raz drugi.
Wadą jest to, że jeśli 2 administratorów kliknie przycisk „autologin” w tym samym czasie, nie uda się zalogować, ale jest to dopuszczalne ryzyko.
Moją główną obawą jest to, że może to być również (nie taki) duży problem bezpieczeństwa. Czy ktoś może zobaczyć coś złego w tym podejściu? lub sugerujesz lepszy?
Zignoruj ​​fakt, że konta klientów można rozdzielić według stron internetowych. Nie jest to ważne i można je łatwo zarządzać.


Czy zwykłe klucze administracyjnego adresu URL nie zapewniłyby tak samo bezpieczeństwa?
kalenjordan

@kalenjordan Problemem nie jest część administracyjna. To wydaje się OK. Moje obawy dotyczą wywoływania adresu URL interfejsu użytkownika w celu automatycznego logowania. Nie mogę tam używać kluczy administratora URL.
Marius

Ach tak, przepraszam. Czy sprawdziłeś magentocommerce.com/magento-connect/login-as-customer-9893.html ? Generuje unikalny rekord dla każdej próby logowania przez administratora, z unikalnym hashem powiązanym z identyfikatorem klienta, który jest używany w kontrolerze frontend.
kalenjordan

@kalenjordan Ha Ha. Nie wiedziałem o tym rozszerzeniu. ale z tego, co opisałeś, jest to samo podejście, które opisałem w pytaniu. :) Spojrzę na to. Dzięki.
Marius

1
@ mageUz.True, ale jak powiedziałem, jest to dopuszczalne ryzyko. Bardziej martwię się tutaj o bezpieczeństwo.
Marius

Odpowiedzi:


9

Ponieważ nikt nie wpadł na dobry powód, aby nie robić tego, o co prosiłem, zakładam, że moja metoda jest w pewnym sensie bezpieczna. Aby nie pozostawiać otwartego pytania, postanowiłem dodać kod jako odpowiedź i oznaczyć go jako zaakceptowany.
Mam więc nowe rozszerzenie Easylife_Simulateo następujących plikach: app/etc/modules/Easylife_Simulte.xml- plik deklaracji:

<?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 - plik konfiguracyjny

<?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 - skrypt instalacyjny - dodaje nowy atrybut klienta:

<?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 - obserwator, aby dodać przycisk w formularzu edycji administratora klienta

<?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 - kontroler administracyjny, który obsługuje kliknięcie przycisku wygenerowanego powyżej.

<?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 - kontroler frontendowy, który wykonuje 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 - pomocnik modułu

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Otóż ​​to. Wydaje mi się, że dla mnie działa. Jak powiedziałem w pytaniu, minusem jest to, że jeśli 2 administratorów naciśnie przycisk logowania dla tego samego klienta (w przybliżeniu) w tym samym czasie, jeden z nich nie zostanie zalogowany. Ale może powtórzyć ten proces kilka sekund później.


Co się stanie, gdy jest wielu klientów?
Milople Inc

@GarthHuff Nie rozumiem twojego pytania. Opisz swój scenariusz.
Marius

myślę, że zmieniłem cały scenariusz. Zastąpiłem pole wprowadzania nazwy użytkownika rozwijaną nazwą użytkownika i loguj się automatycznie, gdy nazwa użytkownika zostanie wybrana z menu rozwijanego. To jest moja implementacja techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc

@GarthHuff. Dzięki za skrypt, ale mój problem dotyczy klientów frontonu, a nie administratorów.
Marius

@Marius, czy planujesz stworzyć wersję Magento 2?
Dan

0

W naszym zespole obsługi klienta stosujemy podobne podejście zwane „ghost ghost”, w którym przycisk administratora jest dostępny za pośrednictwem konta klienta. Nie używamy żadnych niestandardowych atrybutów dla login_key ani niczego podobnego i faktycznie używamy przesłoniętego / dostosowanego loginAction rozszerzonego z Mage_Customer_AccountController do przetwarzania logowania.

Dodatkowo, podczas loginAction, po naszej niestandardowej logice i weryfikacji, używamy Mage_Customer_Model_Session :: setCustomerAsLoggedIn, aby upewnić się, że nie tracimy żadnej funkcji zdarzenia, która może zostać wykonana podczas logowania. Jeśli spojrzysz na tę metodę, zauważysz, że ustawia ona klienta w sesji, a także wywołuje zdarzenie customer_login.

wprowadź opis zdjęcia tutaj

Dzięki takiemu podejściu możemy faktycznie zalogować się do wielu agentów jako ten sam klient, który powinniśmy wybrać (chociaż nie chcielibyśmy, aby wielu agentów dodawało do koszyka / składało zamówienia w tym samym czasie na tym samym koncie).

Używamy tego od dwóch lat bez istotnych problemów w tym czasie.


1
Dzięki za informację. Używam również setCustomerAsLoggedInw moim kodzie, z tego samego powodu, co ty. Ale byłem ciekawy metody, jaką należy zastosować do autologiny. (jeśli to nie jest tajemnica).
Marius

Zbudowaliśmy niestandardowy moduł do obsługi tego, który rozciąga się od podstawowej funkcjonalności logowania do interfejsu użytkownika.
Anthony Leach Jr

Mam to Pytałem o jakiś kod, jeśli to możliwe, lub przynajmniej o ideę kodu. A może niektóre wskazówki, czy mój pomysł jest bezpieczny, czy nie.
Marius
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.