Autologin di frontend dari backend

15

Lihat skenario berikut.
Saya memiliki beberapa modul khusus yang memungkinkan pengguna frontend untuk melakukan beberapa tindakan pada beberapa entitas kustom. (detailnya tidak terlalu penting).
Permintaannya adalah bahwa seorang admin harus dapat login di frontend dengan akun pelanggan (tanpa memiliki kata sandi) dan dapat melakukan tindakan tersebut untuk pelanggan.
Karena Anda tidak dapat menggunakan sesi frontend dari backend dan saya tidak ingin membuat tautan autologin permanen untuk frontend karena mungkin ada lubang keamanan besar inilah yang saya lakukan sejauh ini.

  • tambahkan atribut kosong untuk entitas pelanggan. (sebut saja login_key)
  • tambahkan tombol di backend pada halaman edit pelanggan yang dialihkan ke halaman admin tempat string acak dihasilkan dan disimpan dalam atribut login_key.
  • dalam tindakan yang sama saya mengarahkan admin ke url frontend seperti ini autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(nilai yang dihasilkan pada langkah sebelumnya).
  • di url frontend, jika id pelanggan dan login_keycocok untuk pelanggan tertentu maka saya menetapkan objek pelanggan dalam sesi (seperti masuk) dan menghapus login_keyagar url tidak akan berfungsi di masa mendatang.

Ini bekerja. Maksud saya, saya masuk sebagai pelanggan terpilih dan tautan yang digunakan untuk autologin tidak berfungsi untuk kedua kalinya.
Sisi buruknya adalah jika 2 admin mengklik tombol "autologin" sekitar waktu yang sama, seseorang akan gagal masuk, tetapi ini adalah risiko yang dapat diterima.
Kekhawatiran utama saya adalah bahwa ini mungkin juga masalah keamanan besar (bukan itu). Bisakah seseorang melihat sesuatu yang salah dengan pendekatan ini? atau menyarankan yang lebih baik?
Abaikan fakta bahwa akun pelanggan dapat dipisahkan oleh situs web. Ini tidak penting dan juga dapat dikelola dengan mudah.

Marius
sumber
Bukankah kunci URL admin reguler memberi Anda keamanan yang sama besarnya?
kalenjordan
@kalenjordan Masalahnya bukan pada bagian admin. Jahitannya oke. Kekhawatiran saya adalah ketika memanggil URL frontend untuk autologin. Saya tidak dapat menggunakan kunci URL admin di sana.
Marius
Ah benar, maaf. Sudahkah Anda memeriksa magentocommerce.com/magento-connect/login-as-customer-9893.html ? Ini menghasilkan catatan unik per upaya login oleh admin, dengan hash unik yang terkait dengan ID pelanggan yang digunakan dalam pengontrol frontend.
kalenjordan
@kalenjordan Ha Ha. Saya tidak tahu tentang ekstensi itu. tetapi dari apa yang Anda jelaskan adalah pendekatan yang sama yang saya jelaskan dalam pertanyaan. :) Saya akan melihatnya. Terima kasih.
Marius
1
@ mageUz. Benar, tapi seperti yang saya katakan, itu risiko yang dapat diterima. Saya lebih mementingkan keamanan di sini.
Marius

Jawaban:

9

Karena tidak ada yang datang dengan alasan yang baik untuk tidak melakukan apa yang saya minta, saya berasumsi bahwa metode saya aman. Jadi, agar tidak membiarkan pertanyaan ini terbuka, saya memutuskan untuk menambahkan kode sebagai jawaban dan menandainya sebagai diterima.
Jadi saya memiliki ekstensi baru yang dipanggil Easylife_Simulatedengan file berikut: app/etc/modules/Easylife_Simulte.xml- file deklarasi:

<?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 - file konfigurasi

<?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 - instal skrip - menambahkan atribut pelanggan baru:

<?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 - pengamat untuk menambahkan tombol di formulir edit admin pelanggan

<?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 - pengontrol admin yang menangani klik pada tombol yang dihasilkan di atas.

<?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 - pengendali frontend yang membuat 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 - pembantu modul

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Itu dia. Tampaknya bekerja untuk saya. Seperti yang saya katakan dalam pertanyaan, downside adalah bahwa jika 2 admin menekan tombol login untuk pelanggan yang sama di (kurang-lebih) pada waktu yang sama, salah satunya tidak akan login. Tetapi dia dapat mengulangi prosesnya beberapa detik kemudian.

Marius
sumber
Apa yang terjadi ketika ada banyak pelanggan?
Milople Inc
@ GarthHuff Saya tidak mengerti pertanyaan Anda. Tolong jelaskan skenario Anda.
Marius
saya pikir, saya telah mengubah seluruh skenario yang telah saya lakukan adalah Ganti kotak input nama pengguna dengan drop-down dengan kemungkinan nama pengguna dan login secara otomatis ketika nama pengguna dipilih dari dropdown. Ini adalah techworkslab implementasiku.pixub.com/2014/01/script-for-auto-login
Milople Inc
@GarthHuff. Terima kasih untuk skripnya, tetapi masalah saya terkait dengan pelanggan frontend, bukan admin.
Marius
@Marius apakah Anda berencana membuat versi Magento 2 ini?
Dan
0

Kami menggunakan pendekatan serupa untuk tim layanan pelanggan kami yang disebut "ghost login" di mana kami menyediakan tombol melalui akun pelanggan di admin. Kami tidak menggunakan atribut khusus apa pun untuk login_key atau semacamnya dan sebenarnya menggunakan loginAction yang diganti / disesuaikan yang diperluas dari Mage_Customer_AccountController untuk memproses login.

Selain itu, selama loginAction, setelah logika dan validasi khusus kami, kami menggunakan Mage_Customer_Model_Session :: setCustomerAsLoggedIn untuk memastikan bahwa kami tidak kehilangan fungsionalitas acara apa pun yang dapat dijalankan selama login. Jika Anda melihat metode ini, Anda akan melihat bahwa itu menetapkan pelanggan di sesi serta mengirimkan acara customer_login.

masukkan deskripsi gambar di sini

Dengan pendekatan ini kita sebenarnya dapat memiliki beberapa agen masuk sebagai pelanggan yang sama yang harus kita pilih (walaupun kita tidak ingin memiliki banyak agen yang ditambahkan ke keranjang / menempatkan pesanan pada saat yang sama di akun yang sama).

Kami telah menggunakan ini selama dua tahun sekarang tanpa masalah penting selama waktu itu.

Anthony Leach Jr
sumber
1
Terimakasih atas infonya. Saya juga menggunakan setCustomerAsLoggedInkode saya, untuk alasan yang sama seperti Anda. Tapi saya penasaran dengan metode yang digunakan untuk autologin. (jika itu bukan rahasia).
Marius
Kami telah membangun modul khusus untuk menangani hal ini yang meluas dari fungsi login frontend inti.
Anthony Leach Jr
Saya mengerti. Saya bertanya tentang beberapa kode, jika mungkin, atau setidaknya ide di balik kode. Atau mungkin beberapa petunjuk jika ide saya aman atau tidak.
Marius