Маленький ВЕБ-сервис с большими возможностями

Опубликовал Денис Лазарев (irreal) в раздел Обмен - Интеграция с WEB

Представьте, что у вас есть несколько баз данных, похожих и не похожих друг на друга, возможно, разделенных просторами интернета. Намерение, например, что-то одновременно поменять в них, записать новый элемент справочника, снять однотипные отчеты упирается в волну неприятного предвкушения полазить по терминалкам ради захода в каждую базу, если не предусмотрено средств работы с базами из одного места. ВЕБ-сервисы предоставляют подходящий для интернета транспорт для передачи данных и локализуют ресурсоемкие COM-соединения в пределах связки каждой пары сервер 1С и веб-сервер.

При этом для использования в рамках платформы 1С совершенно не обязательно углубляться в собственную структуру веб-сервиса, разрабатывать его объектную модель и интерфейсы. Достаточно выставить через сервис фунцию вида CmdExec(ParamStructure: string):string и гонять между базами строки, получаемые функцией ЗначениеВСтрокуВнутр(). Если в одном из полей структуры передавать код обработки данных на языке 1С, получаем всемогущий инструмент. Итак, прототип функции веб-сервиса всего лишь

Функция CmdExec(ParamStructure)
 
 СтруктураПараметров = ЗначениеИзСтрокиВнутр(ParamStructure);
 Результат = Новый Структура;
 Если СтруктураПараметров.Свойство("КодОбработки") Тогда
  Попытка
   Выполнить(СтруктураПараметров.КодОбработки);
  Исключение
   Результат.Вставить("Ошибка",ОписаниеОшибки());
  КонецПопытки;
 Иначе 
  Результат.Вставить("Ошибка","WS.ПСГ_Общий.CmdExec: Входная структура не содержит свойства КодОбработки.");
 КонецЕсли; 
 ВозвращаемоеЗначение = ЗначениеВСтрокуВнутр(Результат);
 
 Возврат ВозвращаемоеЗначение;
 
КонецФункции

В прилагаемой демонстрационной базе создан веб-сервис ПСГ_Общий, выставляющий приведенную функцию CmdExec. Для удобства использования применяется функция ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(Адрес,СтруктураПараметров,КодОбработки), принимающая на входе адрес веб-сервера, произвольную структуру параметров и код обработки данных, и возвращающая структуру, созданную функцией CmdExec на целевой базе.

Функция   ВыполнитьКомандуЧерезВебСервис(Адрес,СтруктураПараметров,КодОбработки) Экспорт
 
 СтрокаСоединения = Адрес + "/ws/wsGeneral.1cws?wsdl";
 
 wsAccount = wsAccount();
 Определения = Новый WSОпределения(СтрокаСоединения,wsAccount.Логин,wsAccount.Пароль);
 Прокси = Новый WSПрокси(Определения,"http://www.promstroi-group.ru/general","ПСГ_Общий","ПСГ_ОбщийSoap");
 Прокси.Пользователь = wsAccount.Логин;
 Прокси.Пароль = wsAccount.Пароль;
 
 СтруктураПараметров.Вставить("КодОбработки",КодОбработки);
 ДанныеСтрокой = Прокси.CmdExec(ЗначениеВСтрокуВнутр(СтруктураПараметров));
 Если ДанныеСтрокой = Неопределено Тогда
  ВызватьИсключение("Не удалось получить данные");
 КонецЕсли; 
 
 Данные = ЗначениеИзСтрокиВнутр(ДанныеСтрокой);
 Если Данные.Свойство("Ошибка") Тогда
  ВызватьИсключение(Данные.Ошибка);
 КонецЕсли; 
 
 Возврат Данные;
 
КонецФункции

Здесь wsAccount() возвращает данные для авторизации в виде структуры("Логин,Пароль").


Рассмотрим простейший "Hello, world" для нашего веб-сервиса, команду Ping, выясняющую, доступен ли сервис.

Функция Ping(Адрес) Экспорт
 
 СтруктураПараметров = Новый Структура;
 КодОбработки = "Результат.Вставить(""Статус"",""онлайн"");";
 Результат = ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(стр.АдресWS,СтруктураПараметров,КодОбработки);
 Попытка
  Возврат Результат.Статус;
 Исключение
  Возврат ОписаниеОшибки();
 КонецПопытки; 
 
КонецФункции

Демонстрационная база содержит три других примера: обработку Демо, считывающую произвольный справочник целиком, обработку Тиражирование объектов WS, позволяющую скопировать объект в выбранные базы с совпадающей по составу объектов (но не обязательно реквизитов) структурой.

Для установки демонстрационной базы нужно загрузить прилагаемую dt-выгрузку в новую пустую базу 1С и опубликовать ее на веб-сервере. Далее, в клиенте нужно зайти в справочник Базы данных, и прописать адрес базы в поле Веб-сервер у базы данных База 1, и выставить константу Эта база данных = База1. После этого демонстрационные обработки уже могут общаться с самой этой же базой через ее веб-сервис. Но, конечно, значительно интереснее создать еще одну копию базы, прописать ее в справочник Базы данных как База 2 и посмотреть общение между этими базами.

Не лишне предупредить, что знающий логин и пароль wsAccount(), обладает, фактически правами пользователя wsAccount().Логин в базе, и правами пользователя, под которым работает сервер 1С (или IUSR в файловом варианте), в операционной системе.

Скачать файлы

Наименование Файл Версия Размер
Демонстрационная база
.dt 89,17Kb
26.12.16
11
.dt 1.0.0.0 89,17Kb 11 Скачать

См. также

Комментарии
1. Ярослав Радкевич (WKBAPKA) 201 13.11.13 18:26 Сейчас в теме
что то после пива не совсем вкурил... чуствую, что что-то полезное, но пока не могу понять, что...
2. Денис Лазарев (irreal) 32 13.11.13 18:45 Сейчас в теме
Коротко говоря, отправляешь другой базе код, который нужно выполнить и его параметры структурой, и получаешь ответ структурой. Веб-сервис здесь лишь приспособленный к интернету транспорт. Практически вместо этого можно было бы применить COM-коннектор, но этот, прежде чем заработать, прокачает через инет весь cf. С веб-сервисом тоже прокачает, но не через инет, а между сервером 1с и веб-сервером, через инет пойдет полезный только объем.

Может показаться, что сложно писать код обработки в одной базе, который будет выполняться в другой. Но надо просто правильно распределять код - размещать в базе-сервере основную процедуру, а в базе-клиенте ее использрвать, типа

База - сервер:

Функция ОбщийМодуль.БольшаяИСложнаяТаблица(СтруктураПараметров) Экспорт
...МногаБукав
КонецФункции

База-клиент:

СтруктураПараметров = Новый Структура;
...Заполнение структуры
КодОбработки = "Результат.Вставить(""БольшаяТаблица"",ОбщийМодуль.БольшаяИСложнаяТаблица(СтруктураПараметров));";
Результат = ПСГ_ОбработчикиВебСервисов.ВыполнитьКомандуЧерезВебСервис(стр.АдресWS,СтруктураПараметров,КодОбработки);

// Вот большая таблица и получена:
БольшаяТаблица = Результат.БольшаяТаблица;

Конечно, следует учитывать, в каких терминах будет этот ответ. Если это разные конфигурации, то ссылки "оттуда" потеряют смысл, и нужно возвращать гуиды и наименования. То есть, работа не похожа на работу с объектной системой ком-коннектора. Но в случае, если имеется много одинаковых баз, да еще поддерживается сквозная НСИ, все вообще великолепно.
3. Ийон Тихий (cool.vlad4) 41 13.11.13 22:32 Сейчас в теме
(2) irreal, конечно, замечательно, и идея достаточно простая и понятная, ну кто не думал, сделать Выполнить во внешней базе, и через внешнее соединение и даже через ВК (на этом сайте видел, 1CHServer как-то так называется). Вот только вопрос безопасности остался в сторонке. К сожалению в 1С нет безопасного Выполнить (или мне он неизвестен), т.е. правильно ли я понимаю, что работа таким образом через интернет это серьезная брешь в безопасности ИБ?
4. Денис Лазарев (irreal) 32 13.11.13 23:45 Сейчас в теме
(3) Снижение до уровня защиты в авторизации 1С - безусловно. К тому же, нужно извратиться, чтобы скрыть получение логина и пароля в коде, если к коду имеют доступ, например, аутсорсеры.
С другой стороны, выставить в открытый интернет базу данных я не решился бы и без этого. Интернет интернетом, но в рамках приличия - VNP. На предмет наличия злоумышленника, перехватывающего пакеты внутри сети - да, место слабое.

К слову сказать, мне пока не удалось заставить клиент веб-сервиса 1С авторизоваться по аутентификации ОС, поэтому в коде есть это самое wsAccount() - действие, чью имплементацию я намеренно вынес в отдельную функцию. Если бы удалось ввести виндовую авторизацию, дело обстояло бы гораздо лучше.

Один из способов эмуляции такого поведения на стороне кода в клиенте - вынести конфиденциальную информацию в базу SQL, закрыть доступ к таблицам и выставить только интерфейсную функцию, которая по авторизации ОС решит, что и давать ли вообще. Но уязвимость к перехвату внутри сети остается.
cool.vlad4; +1 Ответить
5. Дмитрий Шерстобитов (DitriX) 2390 14.11.13 12:17 Сейчас в теме
(3) в платформе 8.3 появился Безопасный режим. Т.е. вы работать можете только в среде 1С, и вам не доступно внешнее окружение.
Однако, Выполнить, это не только брешь в безопасности, но и возможность получить кучу проблем. Хотели очистить регистр штрихкдов в 2 базах, и случайно очистили везде.
Т.е. Выполнить - не панацея. Это все равно что сидеть на сервере под учеткой админа, когда для ваших нужд вполне хватает обычного пользователя. А если что то надо админское, то вы запускаете программу от имени админа.

(0)Короче - это вариант не новый, его уже в разных видах представляли тут.
Вот если вы попробуете пройтись по всем аналогичным темам и решить все проблемы там описанные, ответить на все вопросы, вот тогда будет гут.
6. Антон Стеклов (asved.ru) 33 20.11.13 09:56 Сейчас в теме
Зачем применять строковое преобразование, если можно использовать прекрасно сериализующееся ХранилищеЗначения?
7. Денис Лазарев (irreal) 32 20.11.13 17:39 Сейчас в теме
(6) asved.ru, логично, можно и так.
8. Артур Аюханов (artbear) 859 21.11.13 15:08 Сейчас в теме
Очень опасная схема :(
Кто угодно может выполнить код 1С в любой базе :(
9. Денис Лазарев (irreal) 32 21.11.13 21:44 Сейчас в теме
(8) artbear, Для этого "кому угодно" нужно, как минимум, знать логин и пароль веб-сервиса. Выполнение внешних обработок ползователями у нас запрещено, так что здесь не прорвешься, даже зная API. В конце концов, Выполнить() используется, например, в УниверсальныйОбменДаннымиXML. Можно, подсунуть вредоносные правила пользователю этой обработки, если она вдруг ему доступна.
Оставьте свое сообщение