Привет Хабраюзер хочу поделиться своим недавним опытом интеграции двух различных систем.
Возникла задача о передаче данных между 1С (разработка и настройка была отдана на аутсорсинг), которую планируется использовать как основную систему электронного документооборота (ЭДО) и B2B системой (внутренняя разработка), которая написана на PHP (Symfony) и выполняет функции первичного ввода информации в компании.
У меня уже был опыт интеграции B2B с другой B2B. Суть заключалась к передаче JSONа при помощи cURL. Затем возникла задача интеграции системы «Borlas», основанная на Oracle, где также был применен данный подход. На стороне Oracle, правда, использовался свой пакет — аналог cURL в PHP (если будет интересно, могу описать в новой статье).
Как я выяснил, 1С 8.2 тоже умеет посылать GET и POST запросы. Предположил, что если уже все настроено и работает с другими системами, значит, и тут должно сработать. JSON отвергли разработчики 1С, сказав, что формат неподходящий и они признают только XML. Комментарии о том, что это нам даст минимум в размере при передаче данных, а данных действительно получалось очень много, были отвергнуты. В итоге приступили в подготовке 2 систем на основе XML.
Cо своей стороны я написал приемщик запросов из 1С и возврат результатов. Функция по приему переменной в POST, в которой 1Сники должны были подставлять XML.
Формат примерно следующий:
обработчик, который возвращает уже отобранные по условиям записи и формирует XML вида:
Данные могут быть переданные только через HTTPS соединение.
На первый взгляд, кажется, что все просто, но в процессе возникло несколько проблем:
1) аутсорсеры сообщили, что малознакомы с запросами такого рода, и попытались предложить старую проверенную схему:
1. импорт файла из B2B,
2. Загрузка в 1С,
3. Экспорт файла с указанием, что смогли обработать, что нет из 1С,
4. Импорт в Б2Б,
5. и с самого начала…
Схему отвергли, так как нужно быстро, и без участия человека и всяких «кнопочек».
Тогда попросили пример кода. В интернете я «нагуглил» следующий пример:
На сервер стали приходить данные, но пустые, то есть GET и POST были пустые. Я добавил запись что приходит в логи и успешно забыл об этом. Спустя 4 месяца мне была поставлена срочная задача — довести интеграцию до результата (так как прошло много времени, разработчики 1С работают, работают, но в ответ ничего не приходит). Мне поставили 1С и я начал «ковыряться».
Первое — решил поставить Fiddler, чтобы понять что происходит. Заметил, что соединение идет по HTTP, а затем сервер редиректит на HTTPS. Предположил, что по этой причине данные получаются пустыми. Попробовал в Chrome воспроизвести, и получил подтверждение, что данные в POST запросе теряются при редиректе.
Так как разрешать работу по HTTP нельзя, начал изучать почему, ведь указано, что:
В итоге это «Иначе» было выкинуто, и получил ошибку, что некорректный сертификат. Сертификат был само подписной. Разработка интеграции велась на внутренних серверах, где официально купленного сертификата от «Thawte SSL CA» в отличии от PROD сервера. Импорт сертификата во все возможные хранилища не привел к результату.
Поиск по ресурсам привел к тому, что все сертификаты корневые у 1С свои, и на основе них она уже проверяет остальные. Они лежат в тестовом виде в файле «cacert.pem», который расположен в папке «bin», где стоит 1С. Импорт, не так прост, как оказалось.
Для начала надо экспортировать нужный нам сертификат в файл (он у меня уже был в личном хранилище). Запустив «certmgr.msc», найдя сертификат, делаем его экспорт в файл *.cer.
Далее качаем программку Win32OpenSSL и преобразовываем его в тестовый вид.
У меня это получилось так:
MD5 сохраняем, он нам понадобится.
Далее открываем файл «cacert.pem».
Спускаемся в самый низ и добавляем сперва MD5, а потом все содержимое, что получилось в файле «fiddler.pem».
Сохраняем файл.
Перезапускаем 1С (возможно и не надо, но у меня не заработало, поэтому я перезапустил все.
Исходный файл в 1С был приведен в такой вид:
После нажатия на кнопку, пошел запрос по HTTPS и на выходе был получен корректный XML.
Искал, как работает 1С по HTTPS, достаточно много материала, но вот как работать по само подписному сертификату не нашел.
Готов поделиться информацией о злоключениях с настройкой Oracle и B2B.
Там использовался тот же механизм, передача данных в POST запросе, но были свои подводные камни. В принципе, там оказалось все проще.
Возникла задача о передаче данных между 1С (разработка и настройка была отдана на аутсорсинг), которую планируется использовать как основную систему электронного документооборота (ЭДО) и B2B системой (внутренняя разработка), которая написана на PHP (Symfony) и выполняет функции первичного ввода информации в компании.
У меня уже был опыт интеграции B2B с другой B2B. Суть заключалась к передаче JSONа при помощи cURL. Затем возникла задача интеграции системы «Borlas», основанная на Oracle, где также был применен данный подход. На стороне Oracle, правда, использовался свой пакет — аналог cURL в PHP (если будет интересно, могу описать в новой статье).
Как я выяснил, 1С 8.2 тоже умеет посылать GET и POST запросы. Предположил, что если уже все настроено и работает с другими системами, значит, и тут должно сработать. JSON отвергли разработчики 1С, сказав, что формат неподходящий и они признают только XML. Комментарии о том, что это нам даст минимум в размере при передаче данных, а данных действительно получалось очень много, были отвергнуты. В итоге приступили в подготовке 2 систем на основе XML.
Cо своей стороны я написал приемщик запросов из 1С и возврат результатов. Функция по приему переменной в POST, в которой 1Сники должны были подставлять XML.
Формат примерно следующий:
<xml version="1.0"> <KEY>123ABC456</KEY> //ключ авторизации <MODE>get_last_orders </MODE> //операцию что хотят выполнить <LIMIT>4000</LIMIT>//лимит записей что хотят отобрать </xml>
обработчик, который возвращает уже отобранные по условиям записи и формирует XML вида:
<?xml version="1.0" encoding="utf-8" ?> <data> <order> <type1>1</type1> <type>OPS</type> <ref></ref> <id_doc>4853352</id_doc> <start_date>01.01.2013</start_date> <validity>1</validity> <description>Загружено из b2b</description> <additional> <Param> <ParamName>СНИЛС</ParamName> <ParamValue>999999999</ParamValue> </Param> <Param> <ParamName>ФИО клиента</ParamName> <ParamValue>МИХАЙЛОВ МИХАИЛ ЕВГЕНЬЕВИЧ</ParamValue> </Param> <Param> <ParamName>Дата заявления</ParamName> <ParamValue>01.01.2013</ParamValue> </Param> </additional> </order> <order> ... </order> </data>
Данные могут быть переданные только через HTTPS соединение.
На первый взгляд, кажется, что все просто, но в процессе возникло несколько проблем:
1) аутсорсеры сообщили, что малознакомы с запросами такого рода, и попытались предложить старую проверенную схему:
1. импорт файла из B2B,
2. Загрузка в 1С,
3. Экспорт файла с указанием, что смогли обработать, что нет из 1С,
4. Импорт в Б2Б,
5. и с самого начала…
Схему отвергли, так как нужно быстро, и без участия человека и всяких «кнопочек».
Тогда попросили пример кода. В интернете я «нагуглил» следующий пример:
Сервер = "test.com"; Порт = "443"; Попытка НТТР = Новый HTTPСоединение(Сервер, Порт, , , , Истина); Иначе НТТР = Новый HTTPСоединение(Сервер, Порт); КонецЕсли; АдресСкрипта = "/gateway/GetData1C/"; Попытка НТТР.ОтправитьДляОбработки(ИмяФайлаОтправки, АдресСкрипта, ИмяФайлаОтвета, ЗаголовокHTTP); Исключение Сообщить("Неудачная попытка соединения: " + ОписаниеОшибки()); Иначе ЗаписьЖурналаРегистрации("HTTPСоединение", УровеньЖурналаРегистрации.Ошибка, , , "Неудачная попытка соединения: " + ОписаниеОшибки()); КонецЕсли Возврат; КонецПопытки;
На сервер стали приходить данные, но пустые, то есть GET и POST были пустые. Я добавил запись что приходит в логи и успешно забыл об этом. Спустя 4 месяца мне была поставлена срочная задача — довести интеграцию до результата (так как прошло много времени, разработчики 1С работают, работают, но в ответ ничего не приходит). Мне поставили 1С и я начал «ковыряться».
Первое — решил поставить Fiddler, чтобы понять что происходит. Заметил, что соединение идет по HTTP, а затем сервер редиректит на HTTPS. Предположил, что по этой причине данные получаются пустыми. Попробовал в Chrome воспроизвести, и получил подтверждение, что данные в POST запросе теряются при редиректе.
Так как разрешать работу по HTTP нельзя, начал изучать почему, ведь указано, что:
НТТР = Новый HTTPСоединение(Сервер, Порт, , , , Истина); Параметр «Истина» означает что использовать HTTPS, и тут дошло что срабатывает НТТР = Новый HTTPСоединение(Сервер, Порт);
В итоге это «Иначе» было выкинуто, и получил ошибку, что некорректный сертификат. Сертификат был само подписной. Разработка интеграции велась на внутренних серверах, где официально купленного сертификата от «Thawte SSL CA» в отличии от PROD сервера. Импорт сертификата во все возможные хранилища не привел к результату.
Поиск по ресурсам привел к тому, что все сертификаты корневые у 1С свои, и на основе них она уже проверяет остальные. Они лежат в тестовом виде в файле «cacert.pem», который расположен в папке «bin», где стоит 1С. Импорт, не так прост, как оказалось.
Для начала надо экспортировать нужный нам сертификат в файл (он у меня уже был в личном хранилище). Запустив «certmgr.msc», найдя сертификат, делаем его экспорт в файл *.cer.
Далее качаем программку Win32OpenSSL и преобразовываем его в тестовый вид.
У меня это получилось так:
C:\OpenSSL-Win64\bin>openssl x509 -inform der -in С:\fiddler.cer -out С:\fiddler.pem -text -fingerprint -md5 WARNING: can't open config file: /usr/local/ssl/openssl.cnf MD5 Fingerprint=13:BF:73:43:BB:69:19:BA:22:5D:C7:2E:44:85:91:7F
MD5 сохраняем, он нам понадобится.
Далее открываем файл «cacert.pem».
Спускаемся в самый низ и добавляем сперва MD5, а потом все содержимое, что получилось в файле «fiddler.pem».
Сохраняем файл.
Перезапускаем 1С (возможно и не надо, но у меня не заработало, поэтому я перезапустил все.
Исходный файл в 1С был приведен в такой вид:
Процедура ПослатьЗапросНажатие(Элемент) Соединение = ПолучитьHTTPСоединение(); Если Соединение = Неопределено Тогда Сообщить("Не удалось подключиться к серверу, указанному в настройке обмена! Обработка прервана!"); Иначе Источник = АдресФайла; КонецЕсли; ИмяФайла = ФайлРезультат; ИмяПостФайла = ПостФайл; ФайлОтправки = Новый Файл(ИмяПостФайла); РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер()); Заголовки = Новый Соответствие(); Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки); Попытка Соединение.ОтправитьДляОбработки(ИмяПостФайла, Источник, ИмяФайла, Заголовки); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки КонецПроцедуры Функция ПолучитьHTTPСоединение() Экспорт Попытка Соединение = Новый HTTPСоединение(HTTPСервер,"443",,,,Истина); Исключение Сообщить(ОписаниеОшибки()); Соединение = Неопределено; КонецПопытки; Возврат Соединение; КонецФункции Процедура ПриОткрытии() HTTPСервер = "test.com"; АдресФайла = "/gateway/GetData1C"; ПостФайл = "C:\POST_1C\post.txt"; ФайлРезультат = "C:\POST_1C\result.xml"; КонецПроцедуры
После нажатия на кнопку, пошел запрос по HTTPS и на выходе был получен корректный XML.
Искал, как работает 1С по HTTPS, достаточно много материала, но вот как работать по само подписному сертификату не нашел.
Готов поделиться информацией о злоключениях с настройкой Oracle и B2B.
Там использовался тот же механизм, передача данных в POST запросе, но были свои подводные камни. В принципе, там оказалось все проще.
