Реализация протокола удаленного вызова процедур в формате JSON (JSON-RPC)

14.10.19

Администрирование - Удаленное управление

Удалённый вызов процедур (от англ. Remote Procedure Call, RPC) - технология, позволяющая программам вызывать функции и процедуры на удалённых компьютерах (более точная формулировка: "вызывать функции или процедуры в другом адресном пространстве", т.е. это не обязательно другой компьютер). В данной публикации описана реализация этой технологии в 1С. В качестве протокола для передачи сообщений используется JSON (JSON-RPC), что позволяет удалённым системам (например, веб-приложениям) вызывать функции 1С (только те функции, которые определит разработчик).

Скачать исходный код

Наименование Файл Версия Размер
Реализация протокола удаленного вызова процедур в формате JSON (JSON-RPC)
.zip 13,34Kb
24
.zip 1.0.2.1 13,34Kb 24 Скачать

 

Общие сведения.

 

Существует множество способов реализации обмена данными сторонних программ с 1С с использованием HTTP-сервисов. Данная реализация позволяет определить один HTTP-сервис и просто добавлять нужные процедуры в общий модуль без переработки (изменения существующих или добавления новых) HTTP-сервисов. В качестве формата протокола используется JSON.

Ниже приведено краткое описание JSON-RPC 2.0.

Запрос должен содержать три обязательных свойства:

  • method - Строка с именем вызываемого метода.
  • params - Массив данных, которые должны передаваться методу, как параметры.
  • id - Значение любого типа, которое используется для установки соответствия между запросом и ответом.

Так же должна быть передана версия протокола (в нашем случае "2.0") в параметре jsonrpc. В спецификации протокола этот параметр не указан, как обязательный, но в реализации данной публикации его указание обязательно.

Пример запроса для вызова процедуры ПолучитьСчетаКлиента(ИНН, НачалоПериода, КонецПериода) (данная процедура использована в качестве примера, конкретные процедуры определяет разработчик):

{"jsonrpc": "2.0", "method": "ПолучитьСчетаКлиента", "params": ["7705260674", "2019-09-01", "2019-09-30"], "id": 1}

Сервер (в нашем случае - решение на 1С) отсылает ответ, содержащий следующие свойства:

  • result - Результат выполнения метода. Если во время выполнения метода произошла ошибка, то это свойство должно быть установлено в null.
  • error - Код ошибки, если произошла ошибка во время выполнения метода, иначе null.
  • id - То же значение идентификатора, что и в запросе, к которому относится данный ответ (используется для сопоставления самого запроса и его результата, например, если асинхронно отправляется сразу несколько запросов).

Пример ответа:

{"jsonrpc": "2.0", "result": [{"uid": "422f9d5c-1032-11e5-92f1-0050568b35ac", "num": "ТД00-000001", "date": "2019-09-11T16:06:15", "sum": 127125}], "id": 1}

Более подробно с протоколом JSON-RPC можно ознакомиться на википедии.

В данной публикации удалённый вызов процедур 1С реализован в виде расширения. В этом расширении присутствует HTTP-сервис rpc_JSONRPC2. После публикации http-сервиса на веб-сервере сторонние системы (в качестве которой может выступать и другая база 1С) смогут выполнять запросы по адресу http://<адрес_базы>/hs/jsonrpc2.

Вызываемые удалённые процедуры должны располагаться в общем модуле расширения rpc_УдаленныеПроцедурыПереопределяемый.

Особенности реализации 1С.

Для упрощения создания собственных удалённых процедур были реализованы следующие особенности:

  • Передаваемые в запросе JSON строковые значения параметров true и false преобразуются в тип 1С Булево.
  • Передаваемые в запросе JSON строковые значения параметров типа 2019-01-10Т10:23:54 (дата в формате XML) преобразуются в тип 1С Дата.
  • Передаваемые в запросе JSON строковые значения параметров типа GUID преобразуются в тип 1С УникальныйИдентификатор.
  • Удалённая процедура (в 1С функция) должна возвращать только значения, которые могут быть сериализованы в JSON. Исключение составляет тип ТаблицаЗначений. В типовом механизме сериализации JSON этот тип не может использоваться, но в данном решении для упрощения возврата ответа (чтобы разработчик не писал лишний код) таблица значений преобразуется в массив структур.

Для передачи ошибок используется вызов исключения.

Например, вот так можно реализовать обработку ошибок в приведённой выше в качестве примера процедуре ПолучитьСчетаКлиента:

Функция ПолучитьСчетаКлиента(ИНН, НачалоПериода, КонецПериода) Экспорт
	
	Контрагент = НайтиКонтрагентаПоИНН(ИНН);
	Если Контрагент.Пустая() Тогда
		ТекстСообщения = СтрШаблон(НСтр("ru='Не найден клиент с ИНН: %1'"), ИНН);
		ВызватьИсключение ТекстСообщения;
	КонецЕсли; 
	
    ...
	
КонецФункции 

В таком случае, если в запросе будет передан ИНН контрагента, отсутствующего в информационной базе, то клиентом будет получен ответ следующего вида:

{"jsonrpc": "2.0", "error": {"code": -32800, "message": "Не найден клиент с ИНН: 0777123413"}, "id": 1}

Примечание. В данной реализации используются следующие коды ошибок:

  • -32600, "Invalid JSON-RPC" - возвращается, если передан неверный формат сообщения (не удалось прочитать JSON) или отсутствуют обязательные параметры;
  • -32700, "Parse error" - возвращается, если переданы неверные параметры (например, отсутствует параметр method или параметр params не является массивом и т.п.);
  • -32601, "Procedure not found" - вызываемая функция отсутствует в общем модуле rpc_УдаленныеПроцедурыПереопределяемый;
  • -32800, <текст ошибки> - ошибка, возникшая во время выполнения метода (см. пример ответа с ошибкой выше).

 

Перейдём от теории к практике.

 

В качестве примера будем использовать конфигурацию Управление торговлей, редакция 11 (конкретный релиз для примера не имеет значения).

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

В данном случае порядок действий будет следующим:

1. Добавляем в конфигурацию расширение из этой публикации и публикуем HTTP-сервис rpc_JSONRPC2.

2. Открываем общий модуль расширения rpc_УдаленныеПроцедурыПереопределяемый и реализуем процедуру ПолучитьСчетаКлиента:

Функция ПолучитьСчетаКлиента(ИНН, НачалоПериода, КонецПериода) Экспорт
	
	Контрагент = НайтиКонтрагентаПоИНН(ИНН); // Реализация данной функции не представляет проблем, оставим её "за скобками".
	Если Контрагент.Пустая() Тогда
		ТекстСообщения = СтрШаблон(НСтр("ru='Не найден клиент с ИНН: %1'"), ИНН);
		ВызватьИсключение ТекстСообщения;
	КонецЕсли; 
	
	ТаблицаСчетов = Новый ТаблицаЗначений;
	ТаблицаСчетов.Колонки.Добавить("uid", Новый ОписаниеТипов("УникальныйИдентификатор"));
	ТаблицаСчетов.Колонки.Добавить("num", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(11)));
	ТаблицаСчетов.Колонки.Добавить("date", Новый ОписаниеТипов("Дата",,, Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
	ТаблицаСчетов.Колонки.Добавить("sum", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
	
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	СчетНаОплатуКлиенту.Ссылка КАК Ссылка,
	|	СчетНаОплатуКлиенту.Номер КАК num,
	|	СчетНаОплатуКлиенту.Дата КАК date,
	|	СчетНаОплатуКлиенту.СуммаДокумента КАК sum
	|ИЗ
	|	Документ.СчетНаОплатуКлиенту КАК СчетНаОплатуКлиенту
	|ГДЕ
	|	СчетНаОплатуКлиенту.Контрагент = &Контрагент
	|	И СчетНаОплатуКлиенту.Дата МЕЖДУ &НачалоПериода И &КонецПериода");
	Запрос.УстановитьПараметр("Контрагент", Контрагент);
	Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(НачалоПериода));
	Запрос.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода));
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		СтрокаТаблицы = ТаблицаСчетов.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Выборка);
		СтрокаТаблицы.uid = Выборка.Ссылка.УникальныйИдентификатор();
	КонецЦикла; 
	
	Возврат ТаблицаСчетов;
	
КонецФункции 

 

3. Важный момент. Чтобы была возможность выполнять удаленный вызов данной функции нужно добавить её имя в процедуру УдаленныеПроцедуры общего модуля rpc_УдаленныеПроцедуры. Ниже приведён пример такой процедуры:

Функция УдаленныеПроцедуры() Экспорт
	
	УдаленныеПроцедуры = Новый Массив;
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////
	// Необходимо добавить следующие строки:
	//
	УдаленныеПроцедуры.Добавить("ПолучитьСчетаКлиента");
	УдаленныеПроцедуры.Добавить("АннулироватьСчетКлиента");
	///////////////////////////////////////////////////////////////////////////////////////////////////////
	
	Возврат УдаленныеПроцедуры;
	
КонецФункции 

Это сделано для безопасности с целью исключения выполнения произвольного кода, непредусмотренного разработчиком. Дело в том, что для вызова процедур используется метод 1С Выполнить:

Выполнить("Результат = rpc_УдаленныеПроцедурыПереопределяемый." + ИмяМетода + "(" + ... + ")";

Злоумышленник может в параметре JSON params передать строку, например для описанной выше функции

{"jsonrpc": "2.0", "method": "ПолучитьСчетаКлиента(\"7705260674\", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе()", ...}

В результате чего будет выполнен код:

Выполнить("Результат = rpc_УдаленныеПроцедурыПереопределяемый.ПолучитьСчетаКлиента(""7705260674"", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе() ...

Т.е. после выполнения предусмотренного разработчиком метода "ПолучитьСчетаКлиента" начнёт выполняться произвольный код, который выполняться не должен!

Благодаря добавлению имён процедур в методе УдаленныеПроцедуры общего модуля rpc_УдаленныеПроцедуры такая возможность исключается. Для системы в таком случае имя метода будет не "ПолучитьСчетаКлиента", а ПолучитьСчетаКлиента("7705260674", '20190901, '20190930); ВредныйМодуль.УдалитьВсе(). Такая строка не определена в методе УдаленныеПроцедуры общего модуля rpc_УдаленныеПроцедуры, поэтому ни какой код выполняться не будет, а будет выдано сообщение об ошибке.

 

Теперь веб-программисту достаточно будет выполнить POST запрос по адресу http://<адрес_базы>/hs/jsonrpc2 в формате вида

{"jsonrpc": "2.0", "method": "ПолучитьСчетаКлиента", "params": ["7705260674", "2019-09-01", "2019-09-30"], "id": 1}

чтобы получить необходимые данные.

Всё работает, всё хорошо, но возникает новое требование - дать возможность клиенту из личного кабинета аннулировать счёт на оплату. И вот разработчик личного кабинета просит разработчика 1С реализовать такую возможность.

Для этого достаточно вновь открыть общий модуль расширения rpc_УдаленныеПроцедурыПереопределяемый и реализовать новую процедуру АннулироватьСчетКлиента(ИдентификаторСчета).

Процедура АннулироватьСчетКлиента(ИдентификаторСчета) Экспорт
	
	СчетКлиента = Документы.СчетНаОплатуКлиенту.ПолучитьСсылку(ИдентификаторСчета);
	
	МассивСчетов = Новый Массив;
	МассивСчетов.Добавить(СчетКлиента);
	
	Попытка
		Документы.СчетНаОплатуКлиенту.УстановитьПризнакАннулирован(МассивСчетов);
	Исключение
		ЗаписьЖурналаРегистрации("JSON-RPC.АнулироватьСчетКлиента",
			УровеньЖурналаРегистрации.Ошибка,,,
			КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;
	
КонецПроцедуры 

Теперь, когда клиент в личном кабинете в меню, например, выберет команду "Аннулировать счёт", веб-разработчик просто выполнит POST запрос к базе 1С вида

{"jsonrpc": "2.0", "method": "АнулироватьСчетКлиента", "params": ["422f9d5c-1032-11e5-92f1-0050568b35ac"]}

Хочу обратить внимание, что данная процедура не предполагает возвращение результата, поэтому передавать параметр id не нужно (в терминах JSON-RPC это называется уведомлением). Примечание. Использовано для примера, в реальности, конечно, нужно возвращать ошибку, если по какой-то причине не удалось аннулировать счёт, например, если отсутствует счёт с таким уникальным идентификатором.

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

RPC JSON-RPC Обмен

См. также

Подключение по RDP из 1С с автоматическим вводом пароля

Удаленное управление Пароли Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Как дать доступ сотруднику к удаленному рабочему столу (RDP), но при этом не давать пароль доступа?

2 стартмани

25.03.2024    4061    5    dungeonkeeper    1    

11

Диспетчер служб удаленных рабочих столов из 1С для Windows 2019

Удаленное управление Платформа 1С v8.3 Управляемые формы 1С:Бухгалтерия 3.0 Россия Абонемент ($m)

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

1 стартмани

22.12.2023    4117    18    Струнин    4    

22

Теневое подключение к RDP сессии пользователя на Windows Server 2022

Удаленное управление Россия Абонемент ($m)

Маленькая программка для реализации подключения к сессиям пользователя на сервере.

2 стартмани

05.10.2023    1718    9    AActor    1    

7

Хранение логов Ammy Admin

Удаленное управление Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Внешняя обработка считывает историю сеансов Ammyy Admin и хранит в базе 1С. Получает отчет за любой период с группировками по рабочим местам, организациям и операторам.

4 стартмани

03.10.2023    647    0    Uran    0    

2

Организация удаленного доступа RDP на сервер без выделенного IP адреса

Удаленное управление Абонемент ($m)

Настройка RDP подключения на сервер без выделенного IP адреса через сервис NGROK.

1 стартмани

19.09.2023    4237    AlexVogel    10    

9

Система для взаимопомощи сотрудников, демонстрация экрана, запрос помощи, удаленный доступ

Удаленное управление Платформа 1С v8.3 8.3.14 Конфигурации 1cv8 Абонемент ($m)

Расширение обеспечивает возможности подключения одного сотрудника к экрану другого с его согласия в режиме "стажер" - "куратор".

1 стартмани

05.09.2022    3414    4    user739143    0    

14

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

Удаленное управление Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Обработка выводит список сессий пользователей терминальных серверов. По двойному клику запускает удаленное подключение в режиме RDP Shadow - теневое подключение (зеркало). Использует стандартную утилиту mstsc.exe. Работает поиск по списку, сортировка, отбор. Для получения сессий использует стандартную системную утилиту quser.exe, опционально запрашивает поля данных о пользователе у контроллера домена.

1 стартмани

15.08.2022    5161    28    user739143    8    

21

Быстрое подключение к RDP с автоматическим вводом пароля

Удаленное управление Абонемент ($m)

Довольно много специалистов, так или иначе связанных с 1С, работают с базой через удаленный рабочий стол (RDP). В системе даже есть возможность настроить ярлык быстрого подключения к RDP, чтобы сделать подключение максимально быстрым и удобным. К сожалению, если у вас нет прав администратора, либо если групповая политика на вашем компьютере контролируется организацией, у вас могут возникнуть проблемы с автоматическим запоминанием пароля системой. Иными словами, при каждом подключении вам придётся раз за разом заново вводить пароль. Часто такие пароли генерируются автоматически и представляют собой случайные наборы символов, выучить которые порой нереально. Пароль, как правило, сохраняют в текстовом файлике, и раз за разом копируют его оттуда при подключении к RDP. Знакомо? Данная программка поможет вам вводить пароль автоматически. Подключение будет происходить в 1 клик.

1 стартмани

08.08.2022    4071    8    XilDen    5    

4
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. zeegin 114 14.10.19 21:08 Сейчас в теме
https://its.1c.ru/db/v8std#content:770:hdoc

https://ru.m.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0­%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0

Функции Вычислить/Выполнить надо вызывать в безопасном режиме.
Все передаваемые параметры надо экранировать.

Не безопасно.
Glebis; oleg-m; ltfriend; pallid; WizaXxX; vikad; JohnyDeath; Il; +8 Ответить
4. ltfriend 962 15.10.19 19:05 Сейчас в теме
(1) А если функция должна выполнять действия, которые не могут быть выполнены в безопасном режиме (например, в нем используется обращение к файлам)?
В данном случае метод "Выполнить" не производит выполнение произвольных фрагментов кода (например, как обработчики событий в конвертации данных).
"Выполнить" используется для вызова конкретных процедур общего модуля "rpc_УдаленныеПроцедурыПереопределяемый":
Выполнить("Результат = rpc_УдаленныеПроцедурыПереопределяемый." + ИмяМетода + "(" + ... + ")");

Поэтому его можно выполнять в небезопасном режиме. Ведь тот код, который будет выполняться определяет сам разработчик.
Однако, благодаря вашему комментарию я более углубленно задумался о безопасности. И действительно, моя реализация позволяет злоумышленнику выполнить произвольный код. Ведь можно в поле method передать не просто имя метода, а метод с корректными параметрами, потом поставить точку с запятой и написать произвольный код и он будет выполнен!
Например, если передать в поле method вместо ПолучитьСчетаКлиента строку ПолучитьСчетаКлиента(\"7705260674\", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе(), то выполняемая строка примет следующий вид:
Выполнить("Результат = rpc_УдаленныеПроцедурыПереопределяемый.ПолучитьСчетаКлиента(""7705260674"", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе() ...

И после выполнения предусмотренного разработчиком метода "ПолучитьСчетаКлиента" начнёт выполняться произвольный код.
Поэтому в разработку были внесены изменения. Теперь есть дополнительная функция УдаленныеПроцедуры общего модуля rpc_УдаленныеПроцедуры. В ней разработчик должен указать имена функций, которые доступны для вызова.
Т.о. если разработчик определит следующие имена доступных функций:
Функция УдаленныеПроцедуры() Экспорт
	
	УдаленныеПроцедуры = Новый Массив;
	
	////////////////////////////////////////////////////////////­///////////////////////////////////////////
	// Необходимо добавить следующие строки:
	//
	УдаленныеПроцедуры.Добавить("ПолучитьСчетаКлиента");
	УдаленныеПроцедуры.Добавить("АннулироватьСчетКлиента");
	////////////////////////////////////////////////////////////­///////////////////////////////////////////
	
	Возврат УдаленныеПроцедуры;
	
КонецФункции 
Показать

то при передачи в params строки ПолучитьСчетаКлиента(\"7705260674\", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе() ни какого кода выполнено не будет, а будет выдана ошибка, потому что метод ПолучитьСчетаКлиента(\"7705260674\", '20190901', '20190930'); ВредныйМодуль.УдалитьВсе() не определен в функции УдаленныеПроцедуры, а определён метод ПолучитьСчетаКлиента (см. код выше).

А вот с передачей параметров ни каких проблем с безопасностью я не обнаружил. Как вы себе представляете инъекции в запросы 1С через параметры?
Предположим, в процедуре происходит поиска контрагента по ИНН, переданного в качестве параметра:

Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| Контрагенты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ИНН = &ИНН");
Запрос.УстановитьПараметр("ИНН", ИНН);

Какое значение нужно передать в параметре "ИНН", чтобы получить несанкционированные данные, не говоря о том, чтобы злоумышленник мог изменить их передав "чудо строку" через параметр "ИНН" в качестве инъекции?
5. zeegin 114 15.10.19 19:17 Сейчас в теме
(4) В данном случае, конечно, имелось ввиду инъекция не в запросы, а в квери. Т.е. вообще в любое поле, в квери, в заголовки запросов, в коммандную строку. Главное не допустить исполнения произвольного кода.

Безопасно - это не выполнять произвольного кода. В случаях RPC как и впринципе в REST лучше делать контроллер, который будет определять кому передать управление, т.е. то, что определил разработчик.

Я бы сделал просто в переопределяемом модуле процедуру:
ПриОбработкеЗапроса(ИмяМетода, Параметры)

она была бы в роли контроллера и в ней разработчик сможет описать куда роутить исполнение

Если ИмяМетода = "ПолучитьСчетаКлиента" Тогда

МодульРеализацииОбработки.ПолучитьСчетаКлиента(Параметры);

КонецЕсли;
6. ltfriend 962 15.10.19 19:23 Сейчас в теме
(5) соглашусь, что так безопасней, но требует больше кода. Идея была в том, чтобы разработчик просто добавлял новую функцию в модуль rpc_УдаленныеПроцедурыПереопределяемый и она тут же становилась доступна для вызова без дополнительного кода
...
ИначеЕсли ИмяМетода = "..." Тогда
   ....
КонецЕсли


Поэтому я пошёл на компромисс. Сделал отдельную функцию, где разработчик определяет доступные функции. С одной стороны кода стала не намного больше. По сути, добавить одну строку
УдаленныеПроцедуры.Добавить("<имя_процедуры>")

но с другой стороны, по моему мнению, решает проблему с безопасностью.
7. zeegin 114 15.10.19 19:45 Сейчас в теме
(6) Ну тогда правильно сделать в rpc_УдаленныеПроцедурыПереопределяемый процедуру

Процедура ПриОпределенииДопустимыхУдаленныхПроцедур(Процедуры) Экспорт

    Процедуры.Добавить("ПолучитьСчетаКлиента");

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


https://its.1c.ru/db/v8std#content:553
3.2. Переопределяемые общие модули должны содержать только экспортные процедуры.

Ну и всегда надо помнить, что несмотря на то, что HTTP сервисы это серверный контекст, то, что приходит оттуда - идеологически - это клиентский вызов.
https://its.1c.ru/db/v8std#content:678

2. Проникновение небезопасного кода на сервер и его выполнение.

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

Это значит, что на все вызываемые процедуры надо накладывать ограничение

3. Серверные процедуры и функции должны возвращать в форму только окончательный результат расчета.

При этом если пользователь, используемый для удаленного вызова не имеет собственного профиля доступа, или еще хуже, используется привилегированный режим, то требование:

https://its.1c.ru/db/v8std#content:485
3.2. В случаях, когда к экспортной процедуре или функции выполняется обращение в сеансе с недостаточным уровнем прав доступа, должно вызываться исключение стандартного вида.

Будет необходимо дополнительно обработать, чтобы ограничить удаленного пользователя, т.к. стандартной проверки ролей уже не хватит.
8. JohnyDeath 301 16.10.19 05:55 Сейчас в теме
(4)
А вот с передачей параметров ни каких проблем с безопасностью я не обнаружил.

А если вот так:
{"jsonrpc": "2.0", "method": "ПолучитьСчетаКлиента", "params": ["ВредныйМодуль.УдалитьВсе()", "2019-09-01", "2019-09-30"], "id": 1}
9. ltfriend 962 16.10.19 10:05 Сейчас в теме
(8) То значением переданного параметра в функцию будет строка "ВредныйМодуль.УдалитьВсе()".
Строка кода, который выполняется имеет следующий вид
Выполнить(Результат = rpc_УдаленныеПроцедурыПереопределяемый.<Имя_Метода>(Параметры[0], Параметры[1], ..., Параметры[N]));
3. ltfriend 962 15.10.19 17:58 Сейчас в теме
(2) вот из-за заголовка я и не нашёл ту публикацию. Перед своей реализации JSON-RPC я же помнил, что была подобная статья и я там даже оставлял свой комментарий, но перед созданием своей публикации найти её не смог.
10. duhh 236 17.10.19 14:44 Сейчас в теме
Ничего страшного, если в этой ветке задам вопрос про безопасный вызов процедуры. знатокам безопасности.

Вот такой вызов будет безопасным?

Процедура ВыполнитьПроцедуру(ВходящиеДанные)
	
	ДанныеВыполнения = ВходящиеДанные.Данные; 
	
	// Безопасность - проверка имени метода на корректность. Взял из БСП
	Попытка
		Тест = Новый Структура(ДанныеВыполнения.Method, ДанныеВыполнения.Method);
		Если Тест = Неопределено Тогда 
			ВызватьИсключение НСтр("ru = 'Синтетический тест'");
		КонецЕсли;
	Исключение
		ВходящиеДанные.Ошибка = Истина;
		ВходящиеДанные.ТекстОтвета = НСтр("ru='Некорректное значение параметра ИмяМетода.'");
		Возврат;
	КонецПопытки;

	// Безопасность - проверка параметров на корректность. 
	Попытка
		Если Не ТипЗнч(ДанныеВыполнения.Params) = Тип("Структура") Тогда 
			ВызватьИсключение НСтр("ru = 'Тест параметров'");
		КонецЕсли;
	Исключение
		ВходящиеДанные.Ошибка = Истина;
		ВходящиеДанные.ТекстОтвета = НСтр("ru='Некорректное значение параметра Params.'");
		Возврат;
	КонецПопытки;

	СтрокаВыполнения = ДанныеВыполнения.Method + "(" + "{Параметры}" + ")"; 
	
	Если ДанныеВыполнения.Свойство("Params") Тогда
		СтрокаВыполнения = СтрЗаменить(СтрокаВыполнения, "{Параметры}", "ДанныеВыполнения.Params");
	Иначе
		СтрокаВыполнения = СтрЗаменить(СтрокаВыполнения, "{Параметры}", "");
	КонецЕсли; 
	
	Попытка
		Результат = Вычислить(СтрокаВыполнения);
Показать
11. alexqc 150 17.10.19 22:34 Сейчас в теме
В принципе, для безопасности вызова можно проверить что имя метода точно представляет собой идентификатор (последовательность только букв и цифр).
Более того, достаточно проверить отсутствие в имени символа "(" - без скобок никакой команды не напишешь.

А вообще, лично я бы вместо общего модуля делал это в виде макета-словаря: в простейшем виде это будет 1-я колонка -- имя метода в rpc, 2-я -- полный путь вызова (т.е как ОбщийМодуль.ФункцияМодуля либо например РегистрыНакопления.НужныйРегистр.ФункцияМодуляМенеджера).
12. UralKIT 1 25.07.22 09:17 Сейчас в теме
Чем это лучше обычного http-сервиса?
Реализация похожа на большой костыль, RPC ради RPC, без каких то преимуществ перед REST
kabantus; +1 Ответить
13. ltfriend 962 13.03.24 10:39 Сейчас в теме
(12) Это просто реализации протокола JSON-RPC в 1С. Зачем нужен такой "костыль" спросите у разработчиков данного протокола.
p.s. REST - про обмен данными (очень грубо говоря). Получить, записать, обновить.
RPC - выполнение каких-то действий на сервере (вызов процедуры/функции) и получение ответа в качестве результата (опять же грубо говоря, опускаясь до примитивов).
Оставьте свое сообщение