Autologin trên frontend từ phụ trợ


15

Xem kịch bản sau đây.
Tôi có một số mô-đun tùy chỉnh cho phép người dùng frontend thực hiện một số hành động trên một số thực thể tùy chỉnh. (chi tiết không thực sự quan trọng).
Yêu cầu là quản trị viên phải có thể đăng nhập vào frontend bằng tài khoản khách hàng (không cần mật khẩu) và có thể thực hiện những hành động đó cho khách hàng.
Vì bạn không thể sử dụng phiên giao diện từ phụ trợ và tôi không muốn tạo liên kết tự động vĩnh viễn cho giao diện vì đây có thể là một lỗ hổng bảo mật lớn, đây là điều tôi đã làm cho đến nay.

  • thêm một thuộc tính trống cho thực thể khách hàng. (hãy gọi nó login_key)
  • thêm một nút trong phần phụ trợ trên trang chỉnh sửa khách hàng chuyển hướng đến trang quản trị nơi có một chuỗi ngẫu nhiên được tạo và lưu trong thuộc tính login_key.
  • trong cùng một hành động, tôi chuyển hướng quản trị viên đến một url giao diện như thế này autologin/index/index/customer_id/7/login_key/ajkshdkjah123123(giá trị được tạo ở bước trước).
  • tại url frontend, nếu id khách hàng và login_keyphù hợp với một khách hàng cụ thể thì tôi đặt đối tượng khách hàng trong phiên (khi đăng nhập) và xóa login_keyurl để url không hoạt động trong tương lai.

Đường may này để làm việc. Ý tôi là, tôi đã đăng nhập với tư cách là khách hàng đã chọn và liên kết được sử dụng cho autologin không hoạt động lần thứ hai.
Mặt trái là nếu 2 quản trị viên nhấp vào nút "autologin" cùng một lúc, một người sẽ không đăng nhập được, nhưng đây là một rủi ro chấp nhận được.
Mối quan tâm chính của tôi là đây cũng có thể là một vấn đề bảo mật lớn (không phải vậy). Ai đó có thể thấy một cái gì đó sai với phương pháp này? hoặc đề nghị một cái tốt hơn?
Bỏ qua thực tế là các tài khoản khách hàng có thể được phân tách bằng trang web. Điều này không quan trọng và cũng có thể được quản lý dễ dàng.


Các khóa URL quản trị thông thường có cung cấp cho bạn bảo mật không?
kalenjordan

@kalenjordan Vấn đề không phải là phần quản trị. Mà đường may OK. Mối quan tâm của tôi là khi gọi URL frontend cho autologin. Tôi không thể sử dụng khóa URL quản trị viên ở đó.
Marius

À đúng rồi, xin lỗi. Bạn đã kiểm tra magentoc Commerce.com/magento-connect/login-as-customer-9893.html chưa? Nó tạo ra một bản ghi duy nhất cho mỗi lần đăng nhập của quản trị viên, với hàm băm duy nhất được liên kết với ID khách hàng được sử dụng trong bộ điều khiển lối vào.
kalenjordan

@kalenjordan Hà Hà. Tôi không biết về phần mở rộng đó. nhưng từ những gì bạn mô tả là cách tiếp cận tương tự tôi đã mô tả trong câu hỏi. :). Tôi sẽ xem qua nó. Cảm ơn.
Marius

1
@ mageUz.True, nhưng như tôi đã nói, đó là một rủi ro chấp nhận được. Tôi quan tâm nhiều hơn đến an ninh ở đây.
Marius

Câu trả lời:


9

Vì không ai có lý do chính đáng để không làm những gì tôi yêu cầu, tôi cho rằng phương pháp của tôi là an toàn. Vì vậy, để không bỏ ngỏ câu hỏi này, tôi quyết định thêm mã dưới dạng câu trả lời và đánh dấu nó là chấp nhận.
Vì vậy, tôi có một tiện ích mở rộng mới được gọi Easylife_Simulatevới các tệp sau: app/etc/modules/Easylife_Simulte.xml- tệp khai báo:

<?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 - tập tin cấu hình

<?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 - cài đặt tập lệnh - thêm một thuộc tính khách hàng mới:

<?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 - người quan sát để thêm một nút trong biểu mẫu chỉnh sửa quản trị viên khách hàng

<?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 - bộ điều khiển quản trị xử lý nhấp chuột vào nút được tạo ở trên.

<?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 - bộ điều khiển frontend tạo ra 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 - người trợ giúp mô-đun

<?php
class Easylife_Simulate_Helper_Data extends Mage_Core_Helper_Abstract{

}

Đó là nó. Nó đường may để làm việc cho tôi. Giống như tôi đã nói trong câu hỏi, nhược điểm là nếu 2 quản trị viên nhấn nút đăng nhập cho cùng một khách hàng tại (khoảng) cùng một lúc, một trong số họ sẽ không được đăng nhập. Nhưng anh ta có thể lặp lại quá trình vài giây sau đó.


Điều gì xảy ra khi có nhiều khách hàng?
Milople Inc

@GarthHuff Tôi không hiểu câu hỏi của bạn. Hãy mô tả kịch bản của bạn.
Marius

Tôi nghĩ rằng, tôi đã thay đổi toàn bộ kịch bản những gì tôi đã làm là Thay thế hộp nhập tên người dùng bằng trình đơn thả xuống bằng tên người dùng có thể và tự động đăng nhập khi tên người dùng được chọn từ danh sách thả xuống. Đây là công nghệ cấy ghép
Milople Inc

@GarthHuff. Cảm ơn kịch bản, nhưng vấn đề của tôi liên quan đến khách hàng frontend, không phải quản trị viên.
Marius

@Marius bạn có kế hoạch làm một phiên bản Magento 2 này không?
Dan

0

Chúng tôi sử dụng một cách tiếp cận tương tự cho nhóm dịch vụ khách hàng của mình được gọi là "đăng nhập ma" nơi chúng tôi tạo một nút có sẵn thông qua tài khoản khách hàng trong quản trị viên. Chúng tôi không sử dụng bất kỳ thuộc tính tùy chỉnh nào cho login_key hoặc bất cứ thứ gì tương tự và thực sự đang sử dụng một loginAction được ghi đè / tùy chỉnh được mở rộng từ Mage_Customer_AccountContoder để xử lý đăng nhập.

Ngoài ra, trong loginAction, sau logic và xác thực tùy chỉnh của chúng tôi, chúng tôi đang sử dụng Mage_Customer_Model_Session :: setCustomerAsLoggedIn để đảm bảo rằng chúng tôi không bị mất bất kỳ chức năng sự kiện nào có thể được thực thi trong quá trình đăng nhập. Nếu bạn xem phương thức này, bạn sẽ nhận thấy rằng nó đặt khách hàng trong phiên cũng như gửi sự kiện customer_login.

nhập mô tả hình ảnh ở đây

Với cách tiếp cận này, chúng tôi thực sự có thể có nhiều đại lý đăng nhập như cùng một khách hàng mà chúng tôi nên chọn (mặc dù chúng tôi không muốn có nhiều đại lý thêm vào giỏ hàng / đặt hàng cùng một lúc trên cùng một tài khoản).

Chúng tôi đã sử dụng điều này trong hai năm nay mà không có vấn đề đáng chú ý nào trong thời gian đó.


1
Cảm ơn bạn về thông tin. Tôi cũng sử dụng setCustomerAsLoggedInmã của mình, với cùng lý do như bạn. Nhưng tôi tò mò về phương pháp sử dụng cho autologin. (nếu đó không phải là một bí mật).
Marius

Chúng tôi đã xây dựng một mô-đun tùy chỉnh để xử lý việc này mở rộng từ chức năng đăng nhập lối vào lõi.
Anthony Leach Jr

Tôi đã hiểu. Tôi đã hỏi về một số mã, nếu có thể, hoặc ít nhất là ý tưởng đằng sau mã. Hoặc có thể một số gợi ý nếu ý tưởng của tôi an toàn hay không.
Marius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.