Зачем нужно свойство «Вызов сервера» в общем модуле 1С и как его правильно использовать?

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

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

Механизм работы флага «Вызов сервера»

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

Если попытаться вызвать метод такого чисто серверного модуля напрямую из клиентского кода (например, из процедуры формы с директивой &НаКлиенте), платформа выдаст ошибку времени выполнения: метод не обнаружен на клиенте. Клиентский контекст попросту не знает о существовании методов серверного модуля, так как у него нет интерфейса взаимодействия с ними.

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

Почему нельзя ставить эту галку во всех серверных модулях подряд?

Казалось бы, самое простое решение — включить «Вызов сервера» во всех общих модулях, чтобы избавиться от ограничений доступности. Однако стандарты разработки фирмы «1С» категорически запрещают подобный подход по ряду критических причин. Проанализируем эти причины по шагам:

  1. Безопасность и поверхность атаки (API). Любая экспортная процедура или функция общего модуля с флагом «Вызов сервера» становится открытой сетевой точкой входа. В тонком и веб-клиенте обращения к серверу передаются по протоколу HTTP/HTTPS в сериализованном виде. Это означает, что потенциальный злоумышленник или нестандартный клиент может отправить прямой запрос на выполнение метода с любыми параметрами в обход проверок интерфейса формы. Если модуль выполняет критические операции, его нельзя делать открытым для прямого вызова.
  2. Защита привилегированного режима. В общих модулях с установленным признаком Привилегированный флаг «Вызов сервера» включать категорически запрещено. Если неавторизованный пользователь сможет с клиента вызвать метод привилегированного модуля напрямую, произойдет неконтролируемое повышение прав в обход RLS и ролевой модели. По этим же соображениям в модулях вызова сервера запрещено вызывать метод УстановитьПривилегированныйРежим().
  3. Ограничения типов данных (сериализация). При межконтекстном вызове данные упаковываются для передачи по сети. Передать с клиента на сервер или вернуть обратно мутабельные объекты платформы (например, ТаблицаЗначений, ДеревоЗначений, СправочникОбъект или ДокументОбъект) невозможно — возникнет исключение. Поэтому модули, рассчитанные на вызов с клиента, должны оперировать исключительно сериализуемыми типами (примитивные типы, структуры, массивы, ссылки).
  4. Производительность запуска клиента. Для каждого общего модуля с признаком вызова сервера на клиентское рабочее место передаются метаданные для генерации интерфейсных вызовов. Избыточное количество таких модулей увеличивает объем служебного трафика и замедляет запуск пользовательского сеанса.

Архитектурный шаблон «Тонкий фасад» (стандарт БСП)

Разберем, почему в Библиотеке стандартных подсистем (БСП) для каждой функциональной подсистемы создается сразу несколько общих модулей. Это не избыточность, а строгое разделение ответственности по контекстам:

  1. ИмяПодсистемыКлиентСервер — модуль компилируется и на клиенте, и на сервере. В нем содержится вспомогательная логика, не требующая обращения к базе данных (проверка форматов, математические расчеты, структуры). Вызовы методов внутри такого модуля не инициируют сетевых обращений.
  2. ИмяПодсистемы (чистый сервер) — модуль содержит тяжелую серверную бизнес-логику, выполняет запросы, транзакции, модификацию объектов. Флаг вызова сервера снят, поэтому модуль надежно защищен от несанкционированного прямого вызова с клиента.
  3. ИмяПодсистемыВызовСервера — фасадный модуль. Содержит минимальное количество компактных функций, которые принимают с клиента примитивные параметры, валидируют их, вызывают внутреннюю логику из чисто серверного модуля и возвращают клиенту только необходимый минимум данных.

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

Сначала опишем внутреннюю логику в общем модуле РасчетСкидокСервер (свойства: Сервер, без вызова сервера):


// Модуль: РасчетСкидокСервер
// Свойства: Сервер = Истина, Вызов сервера = Ложь

Функция РассчитатьПерсональнуюСкидкуПоБазе(СсылкаКлиент, СуммаПозиции) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Партнеры.ПроцентСкидки КАК ПроцентСкидки
        |ИЗ
        |	Справочник.Партнеры КАК Партнеры
        |ГДЕ
        |	Партнеры.Ссылка = &СсылкаКлиент";
    
    Запрос.УстановитьПараметр("СсылкаКлиент", СсылкаКлиент);
    Результат = Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        Возврат 0;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    
    Возврат Окр((СуммаПозиции * Выборка.ПроцентСкидки) / 100, 2);
    
КонецФункции

Теперь реализуем безопасную точку входа для клиента в модуле РасчетСкидокВызовСервера (свойства: Сервер, Вызов сервера):


// Модуль: РасчетСкидокВызовСервера
// Свойства: Сервер = Истина, Вызов сервера = Истина

Функция ПолучитьСкидкуДляСтроки(Знач КлиентСсылка, Знач СуммаДокумента) Экспорт
    
    // Проверяем корректность входных параметров
    Если Не ЗначениеЗаполнено(КлиентСсылка) Или СуммаДокумента <= 0 Тогда
        Возврат 0;
    КонецЕсли;
    
    // Делегируем выполнение защищенному серверному модулю
    Возврат РасчетСкидокСервер.РассчитатьПерсональнуюСкидкуПоБазе(КлиентСсылка, СуммаДокумента);
    
КонецФункции

И вызовем подготовленный фасадный метод непосредственно из модуля формы:


&НаКлиенте
Процедура КлиентПриИзменении(Элемент)
    
    СуммаСкидки = РасчетСкидокВызовСервера.ПолучитьСкидкуДляСтроки(
        Объект.Контрагент, 
        Объект.СуммаДокумента
    );
    
    Объект.Скидка = СуммаСкидки;
    
КонецПроцедуры

Альтернативы использованию общих модулей вызова сервера

Выясним, когда создавать отдельный общий модуль вовсе не требуется:

  1. Директива &НаСервереБезКонтекста в форме. Если серверное действие необходимо только конкретной форме документа или справочника, выносить его в общий модуль нет необходимости. Достаточно объявить неконтекстную серверную процедуру или функцию прямо в модуле формы. Это работает быстрее, так как не передает контекст формы по сети и не загромождает дерево метаданных конфигурации.
  2. Модули менеджеров объектов. Если логика напрямую относится к справочнику или документу (например, формирование печатной формы или получение настроек по умолчанию), ее удобно располагать в модуле менеджера объекта метаданных. К экспортным методам модуля менеджера также можно обращаться с клиента при соответствующих правах доступа.

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

← На главную