Как адаптировать и протестировать дополнительные обработки и расширения для работы в 1С:Фреш?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

Переход из локального (on-premise) режима работы в облачный сервис 1С:Фреш (1C:Fresh) накладывает на разработчика ряд жестких архитектурных ограничений. Код, который годами безупречно работал на компьютерах пользователей, в облаке часто блокируется системой безопасности. Это связано с тем, что в модели SaaS (Software as a Service) базы данных множества клиентов физически располагаются на одном серверном кластере. Неоптимизированный или небезопасный алгоритм одного пользователя может нарушить стабильность всей системы или привести к утечке конфиденциальной информации.

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

Почему локальные обработки «не взлетают» во Фреше: требования аудита и особенности архитектуры

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

  1. Полный отказ от COM-объектов. Серверная инфраструктура облака фирмы «1С» функционирует под управлением операционной системы Linux. Популярные конструкции вида Новый COMОбъект("Excel.Application") или работа со сторонними Windows-библиотеками (DLL) на сервере физически невозможны. Для импорта и экспорта файлов xls, doc, xml необходимо использовать исключительно штатные кроссплатформенные средства платформы, такие как объект ТабличныйДокумент, а также специализированные механизмы ЧтениеXML, ЗаписьXML или средства работы с JSON.
  2. Контроль внешних сетевых запросов. Безопасный режим по умолчанию блокирует любые попытки кода связаться с внешними веб-сервисами. Если вашей обработке требуется загрузить данные с сайта, отправить СМС-уведомление или обменяться информацией с CRM, эти действия должны быть предварительно задекларированы. В программном интерфейсе БСП (модуль объекта, функция СведенияОВнешнейОбработке()) разработчик обязан явно перечислить все внешние интернет-ресурсы (указав протокол, адрес и порт), к которым планируется обращение.
  3. Использование уникальных префиксов в расширениях. Любые добавляемые объекты метаданных, новые реквизиты, роли, формы или общие модули в расширении должны иметь строго заданный префикс разработчика (например, ПрефиксРазработчика_ИмяРеквизита). Это исключает конфликты имен при последующих автоматических обновлениях конфигурации со стороны вендора.
  4. Открытость исходного кода. Аудиторы Фреша должны контролировать каждую строчку исполняемого алгоритма. Наличие обфусцированного (запутанного) кода, использование внешних скомпилированных компонент без исходников или поставка модулей без исходных текстов гарантирует отклонение публикации.

Рассмотрим структуру функции регистрации обработки, учитывающую требования безопасного режима и декларирование необходимых разрешений:


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.БезопасныйРежим = Истина;
    
    // Обязательно декларируем необходимость подключения к внешнему API
    ЗапросыРазрешений = Новый Массив;
    
    // Пример запроса разрешения на использование HTTP-соединения со сторонним сайтом
    Протокол = "https";
    АдресСайта = "api.myservice.ru";
    Порт = 443;
    ОписаниеРазрешения = "Необходимо для отправки данных интеграции";
    
    Запрос = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(Протокол, АдресСайта, Порт, ОписаниеРазрешения);
    ЗапросыРазрешений.Добавить(Запрос);
    
    ПараметрыРегистрации.Разрешения = ЗапросыРазрешений;
    
    Возврат ПараметрыРегистрации;

КонецФункции

Как самостоятельно протестировать разработку локально перед отправкой на аудит

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

Во-первых, принудительно активируем безопасный режим платформы в локальной копии базы данных. Для этого в функции СведенияОВнешнейОбработке() мы устанавливаем флаг ПараметрыРегистрации.БезопасныйРежим = Истина. При запуске такой обработки через механизм «Дополнительные отчеты и обработки» в файловой базе платформа сразу выдаст предупреждение и заблокирует операцию при наличии любых критических нарушений (например, попытке прямой записи файлов на диск сервера или работы с запрещенными объектами ОС).

Во-вторых, воспользуемся специализированной обработкой «ПодготовкаОбработкиКПубликацииВМоделиСервиса», входящей в состав дистрибутивов Библиотеки стандартных подсистем (БСП). Данная утилита эмулирует облачную среду Фреша, проверяет валидность структуры XML-описания вашей внешней обработки, тестирует корректность заполнения реквизитов и указывает на потенциально опасные конструкции в кодовой базе.

В-третьих, крайне важно протестировать работу интерфейса в режиме веб-клиента. Поскольку пользователи облака работают преимущественно через браузеры, ваш код не должен использовать синхронные вызовы и модальные окна. Модальные формы полностью заблокированы в современных браузерах. Нам необходимо заменить устаревшие методы на их асинхронные аналоги:

Посмотрим на пример правильной организации интерактивного диалога с пользователем в веб-клиенте:


&НаКлиенте
Процедура ВыполнитьДействие(Команда)

    ПараметрыОповещения = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЭтотОбъект);
    ТекстВопроса = "Вы действительно хотите запустить процесс обработки табличной части?";
    
    ПоказатьВопрос(ПараметрыОповещения, ТекстВопроса, РежимДиалогаВопрос.ДаНет);

КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияВопроса(РезультатВопроса, ДополнительныеПараметры) Экспорт

    Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
        // Запускаем серверную процедуру обработки данных
        ВыполнитьОбработкуДанныхНаСервере();
    КонецЕсли;

КонецПроцедуры

Где и как хранить настройки расширений и обработок в модели сервиса?

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

Для надежного и безопасного хранения конфигурационных параметров мы рекомендуем использовать штатные подсистемы БСП и механизмы платформы.

Способ 1. Использование регистров безопасного хранения БСП (Рекомендуемый)

В Библиотеке стандартных подсистем предусмотрены системные регистры, спроектированные специально для изоляции и защиты конфиденциальных данных. Для разделенных приложений Фреша идеально подходит регистр БезопасноеХранилищеДанныхОбластейДанных.

В качестве измерения Владелец в этом регистре можно использовать уникальный строковый идентификатор вашей разработки (например, GUID или символьный код интеграции длиной до 128 символов). Все параметры упаковываются в структуру и сериализуются в ресурс Данные, который имеет тип ХранилищеЗначения. Чтение и запись в данный регистр осуществляются в привилегированном режиме.

Давайте проанализируем программную реализацию записи и считывания настроек:


// Функция записывает параметры авторизации в безопасное хранилище текущей области данных
Процедура ЗаписатьПараметрыИнтеграции(КлючНастроек, СтруктураПараметров) Экспорт

    УстановитьПривилегированныйРежим(Истина);
    
    ХранилищеЗначений = Новый ХранилищеЗначения(СтруктураПараметров);
    
    МенеджерЗаписи = РегистрыСведений.БезопасноеХранилищеДанныхОбластейДанных.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Владелец = КлючНастроек;
    МенеджерЗаписи.Данные = ХранилищеЗначений;
    
    Попытка
        МенеджерЗаписи.Записать();
    Исключение
        ЗаписатьЛогОшибки("Не удалось сохранить настройки безопасности: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение "Ошибка сохранения конфигурации сервиса.";
    КонецПопытки;

КонецПроцедуры

// Функция извлекает ранее сохраненные параметры
Функция ПолучитьПараметрыИнтеграции(КлючНастроек) Экспорт

    УстановитьПривилегированныйРежим(Истина);
    
    МенеджерЗаписи = РегистрыСведений.БезопасноеХранилищеДанныхОбластейДанных.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Владелец = КлючНастроек;
    МенеджерЗаписи.Прочитать();
    
    Если МенеджерЗаписи.Выбран() Тогда
        Возврат МенеджерЗаписи.Данные.Получить();
    КонецЕсли;
    
    Возврат Неопределено;

КонецФункции

Способ 2. Использование ХранилищаОбщихНастроек с виртуальным пользователем

Если вам требуется организовать хранение системных настроек в рамках одной области данных (абонента) без привязки к конкретному физическому пользователю базы данных, можно применить классический разработческий прием. Мы можем сохранять структуру данных через стандартный механизм платформы ХранилищеОбщихНастроек, используя имя виртуального системного пользователя.

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

Посмотрим на пример реализации данного метода:


// Сохранение настроек под виртуальным пользователем
Процедура СохранитьНастройкиПодВиртуальнымПользователем(ИмяОбъекта, СтруктураНастроек) Экспорт

    УстановитьПривилегированныйРежим(Истина);
    
    ВиртуальныйПользователь = "#КонфигурацияРасширенияФреш";
    КлючОбъекта = "ПараметрыИнтеграции_" + ИмяОбъекта;
    
    ХранилищеОбщихНастроек.Сохранить(
        КлючОбъекта, 
        "СистемныеНастройки", 
        СтруктураНастроек, , 
        ВиртуальныйПользователь
    );

КонецПроцедуры

// Восстановление настроек виртуального пользователя
Функция ВосстановитьНастройкиВиртуальногоПользователя(ИмяОбъекта) Экспорт

    УстановитьПривилегированныйРежим(Истина);
    
    ВиртуальныйПользователь = "#КонфигурацияРасширенияФреш";
    КлючОбъекта = "ПараметрыИнтеграции_" + ИмяОбъекта;
    
    Возврат ХранилищеОбщихНастроек.Загрузить(
        КлючОбъекта, 
        "СистемныеНастройки", , 
        ВиртуальныйПользователь
    );

КонецФункции

Подведем итоги

Разработка дополнительных обработок и расширений для облака 1С:Фреш требует от специалиста глубокого понимания принципов разделения данных и безопасности. Перевод кода в безопасный режим, своевременное декларирование внешних интернет-ресурсов, переход на асинхронные методы веб-клиента и использование штатных регистров БСП для хранения настроек позволят вам создавать стабильные, масштабируемые и безопасные решения, которые без труда пройдут любые проверки верификаторов и аудиторов фирмы «1С».

← На главную