Как стать автором
Обновить

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

Время на прочтение3 мин
Количество просмотров5.6K
Всем привет!

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

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

В итоге появился компонент 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() {

    }

}

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

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

Спасибо за внимание.
Теги:
Хабы:
Всего голосов 3: ↑3 и ↓0+3
Комментарии4

Публикации

Истории

Работа

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань