Автологин на интерфейсе от бэкэнда


15

Смотрите следующий сценарий.
У меня есть некоторый пользовательский модуль, который позволяет внешнему пользователю выполнять некоторые действия с некоторыми пользовательскими объектами. (детали не очень важны).
Запрос заключается в том, что администратор должен иметь возможность войти в систему с учетной записью клиента (без пароля) и иметь возможность выполнять эти действия для клиента.
Поскольку вы не можете использовать сеанс внешнего интерфейса из внутреннего интерфейса, и я не хочу создавать постоянную ссылку автологина для внешнего интерфейса, поскольку это может быть большой дырой в безопасности, это то, что я делал до сих пор.

  • добавить пустой атрибут для объекта клиента. (давайте назовем это login_key)
  • добавьте кнопку в бэкэнд на странице редактирования клиента, которая перенаправляет на страницу администратора, где случайная строка генерируется и сохраняется в атрибуте login_key.
  • в том же действии я перенаправляю администратора на URL внешнего интерфейса, как это autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(значение, созданное на предыдущем шаге).
  • по внешнему URL-адресу, если идентификатор клиента login_keyсовпадает с конкретным клиентом, тогда я устанавливаю объект клиента в сеансе (после входа в систему) и удаляю, login_keyчтобы URL-адрес не работал в будущем.

Это швы на работу. Я имею в виду, я вошел в систему как выбранный клиент, и ссылка, используемая для автологина, не работает во второй раз.
Недостатком является то, что если два администратора одновременно нажмут кнопку «autologin», один из них не сможет войти в систему, но это приемлемый риск.
Моя главная проблема заключается в том, что это также может быть (не так) большой проблемой безопасности. Может ли кто-то увидеть что-то не так с этим подходом? или предложить лучший?
Игнорируйте тот факт, что учетные записи клиентов могут быть разделены по веб-сайту. Это не важно, а также легко управляется.


Разве обычные админские URL-ключи не обеспечат вам такой же безопасности?
Календжордан

@kalenjordan Проблема не в админке. Это швы хорошо. Меня беспокоит, когда я вызываю внешний интерфейс URL для autologin. Я не могу использовать ключи URL администратора там.
Мариус

Ах да, извините. Вы проверили magentocommerce.com/magento-connect/login-as-customer-9893.html ? Он генерирует уникальную запись для каждой попытки входа в систему администратором, с уникальным хешем, связанным с идентификатором клиента, который используется в контроллере внешнего интерфейса.
Календжордан

@kalenjordan Ха Ха. Я не знал об этом расширении. но из того, что вы описали, тот же подход, который я описал в этом вопросе. :). Я посмотрю на это. Благодарю.
Мариус

1
@ mageUz.True, но, как я уже сказал, это приемлемый риск. Я больше обеспокоен безопасностью здесь.
Мариус

Ответы:


9

Поскольку ни у кого не было веской причины не делать то, что я просил, я предполагаю, что мой метод безопасен. Поэтому, чтобы не оставлять этот вопрос открытым, я решил добавить код в качестве ответа и отметить его как принятый.
Итак, у меня есть новое расширение, которое называется Easylife_Simulateследующими файлами: app/etc/modules/Easylife_Simulte.xml- файл декларации:

<?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 - файл конфигурации

<?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 - установить скрипт - добавляет новый атрибут клиента:

<?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 - наблюдатель, чтобы добавить кнопку в форме редактирования администратора клиента

<?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 - контроллер администратора, который обрабатывает нажатие на сгенерированную выше кнопку.

<?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 - контроллер внешнего интерфейса, который производит автологин.

<?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 - модуль помощник

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Вот и все. Это похоже на работу для меня. Как я уже сказал в этом вопросе, недостатком является то, что если 2 администратора нажимают кнопку входа в систему для одного и того же клиента (приблизительно) в одно и то же время, один из них не будет авторизован. Но он может повторить процесс через несколько секунд.


Что происходит, когда есть несколько клиентов?
Milople Inc

@GarthHuff Я не понимаю твой вопрос. Пожалуйста, опишите ваш сценарий.
Мариус

я думаю, я изменил весь сценарий, и я заменил поле ввода имени пользователя раскрывающимся списком с возможным именем пользователя и автоматически войду в систему, когда имя пользователя выбрано из раскрывающегося списка. Это моя реализация techworkslab.pixub.com/2014/01/script-for-auto-login
Milople Inc

@GarthHuff. Спасибо за сценарий, но моя проблема связана с внешними клиентами, а не администраторами.
Мариус

@ Мариус, ты планируешь сделать версию для Magento 2?
Дан

0

Мы используем аналогичный подход для нашей команды обслуживания клиентов, который называется «призрачный логин», где мы делаем кнопку доступной через учетную запись клиента в админке. Мы не используем никаких пользовательских атрибутов для login_key или чего-либо подобного и фактически используем переопределенную / настроенную функцию loginAction, расширенную от Mage_Customer_AccountController для обработки входа в систему.

Кроме того, во время loginAction, после нашей пользовательской логики и проверки, мы используем Mage_Customer_Model_Session :: setCustomerAsLoggedIn, чтобы гарантировать, что мы не теряем функциональность событий, которая может быть выполнена во время входа в систему. Если вы посмотрите на этот метод, вы заметите, что он устанавливает клиента в сеансе, а также отправляет событие customer_login.

введите описание изображения здесь

При таком подходе мы можем фактически сделать так, чтобы несколько агентов входили в систему как один и тот же клиент, которого мы выбрали (хотя мы не хотели бы, чтобы несколько агентов добавляли в корзину / размещали заказы одновременно на одном и том же счете).

Мы использовали это в течение двух лет без каких-либо заметных проблем в течение этого времени.


1
Спасибо за информацию. Я также использую setCustomerAsLoggedInв своем коде, по той же причине, что и вы. Но мне было любопытно, какой метод использовать для аутологина. (если не секрет).
Мариус

Мы создали специальный модуль для обработки этого, который выходит за рамки основных функций входа в веб-интерфейс.
Энтони Лич младший

Я понял. Я спрашивал о каком-то коде, если возможно, или, по крайней мере, об идее кода. Или, может быть, некоторые указатели, если моя идея безопасна или нет.
Мариус
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.