Быстрая авторизация в Битрикс, или как переключаться между пользователями без ввода пароля

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Всем привет!

Не так давно на работе в рамках тестирования нового бизнес-процесса мне понадобилась возможность авторизации под разными пользователями.

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

В итоге появился компонент QuickAuth, о котором и пойдет речь ниже.

Вот так выглядит компонент на странице:

image

А вот так он подключается на любой странице:

$APPLICATION->IncludeComponent('ramapriya:quick.auth', '', []);

Выбор пользователя происходит с помощью системного компонента main.user.selector

Чтобы максимально разделить логику и представление, в шаблоне я оставил только сам компонент выбора пользователя и кнопку отправки его ID на сервер. Перед этим, естественно, подключил все необходимые UI-библиотеки:

// template.php

foreach($arResult['extensions'] as $ext) {
    Extension::load($ext);
}

?>
<p><?=Loc::getMessage('QA_SELECT_USER_TEXT')?></p>
<div class="ui-ctl ui-ctl-w25 form-data">
<?php
        $APPLICATION->IncludeComponent('bitrix:main.user.selector', '', $arResult['select_user_component_params']);
?>    
</div>
<div class="ui-ctl ui-ctl-w25 form-data">
        <button id="authorize" class="ui-btn ui-btn-primary"><?=Loc::getMessage('QA_BUTTON_TEXT')?></button>    
</div>

Сам массив нужных расширений формируется и записывается в $arResult в классе компонента

В последнее время я люблю использовать на фронте Vuejs, благо Битрикс поддерживает его из коробки. Но из-за того, что нет прямого доступа к коду выбора пользователя, данный вариант отпал сразу, и выбор был сделан в пользу нативного JS, получающего ID из main.user.selector и отправляющего его на сервер с помощью битриксового метода BX.ajax.runComponentAction:

// script.js

window.onload = function() {

    let userId;
    
    const input = document.getElementById('select_user');
    const button = document.getElementById('authorize');

    input.addEventListener('change', () => {
        userId = input.value;
    })

    button.addEventListener('click', () => {
        if(!userId) {
            alert('Пользователь не выбран');
        } else {
            const request = sendAjax('ramapriya:quick.auth', 'sendUserId', 'class', {
                user: userId
            });

            request.then(response => {
                if(response.result === 'error') {
                    alert(response.error_description)
                } else {
                    window.location.reload(true)
                }
            })
        }
    })

    async function sendAjax(component, action, mode, params = {}) {

        const request = await BX.ajax.runComponentAction(component, action, {
            mode: mode,
            data: params
        });

        return await request.data
    }
    
}

За прием данных в классе компонента отвечает метод sendUserIdAction. Он обрабатывает запрос с помощью объекта Request, а также вызывает метод, авторизующий нужного пользователя:

// class.php

private function authorize($userId) {

        $USER = new CUser;

        if($USER->Authorize($userId)) {
            return true;
        } else {
            throw new SystemException('Ошибка авторизации');
        }

    }

    public function sendUserIdAction() {

        $request = Context::getCurrent()->getRequest();

        if(!$request['user']) {

            $result = [
                'result' => 'error',
                'error_description' => Loc::getMessage('QA_AJAX_RESPONSE_ERROR_DESCRIPTION')
            ];

        }

        $userId = (int) $request['user'];

        try {
            if($this->authorize($userId)) {
                $result = [
                    'result' => 'success'
                ];
            }
        } catch(SystemException $e) {
            $result = [
                'result' => 'error',
                'error_description' => $e->getMessage()
            ];
        }

        return $result;

    }


Важное дополнение: для того, чтобы можно было отправлять AJAX-запрос к компоненту, класс компонента должен унаследоваться от интерфейса Controllerable, а также объявить метод configureActions.

// class.php

use Bitrix\Main\Engine\Contract\Controllerable;
use Bitrix\Main\Engine\ActionFilter;

class QuickAuthComponent extends CBitrixComponent implements Controllerable {

    public function configureActions() {

    }

}

Я не буду цитировать здесь весь код компонента — кому интересно, посмотрят на гитхабе (ссылка выше).

В заключении скажу, что написанное решение сильно упростило мне тестирование бизнес-процессов, т.к. позволило быстро переключаться между пользователями, не заходя в админку.

Спасибо за внимание.
Источник: https://habr.com/ru/post/508316/


Интересные статьи

Интересные статьи

Дальше будут размышления, проверенные рецепты и подводные камни. За последние годы мы съездили штук на 15 или больше таких крупных мероприятий как ISE, CeBIT, InfoComm, GITEX, Ent...
Новый сервис WebWormHole работает как портал, через который файлы передаются с компьютера на другой. Нажимаете кнопку New Wormhole — и получаете код для входа. Человек с другой стороны вводит...
Многие программисты думают, что Quick Sort — самый быстрый алгоритм из всех существующих. Отчасти это так. Но работает она действительно хорошо только если правильно выбран опорный элемент (тогда...
Сравнивать CRM системы – дело неблагодарное. Очень уж сильно они отличаются в целях создания, реализации, в деталях.
В 1С Битрикс есть специальные сущности под названием “Информационные блоки, сокращенно (инфоблоки)“, я думаю каждый с ними знаком, но не каждый понимает, что это такое и для чего они нужны