Особенности реализации доступа по протоколу OAuth 1.0a в случае, если в запросе есть параметры

03.01.21

Интеграция - WEB-интеграция

Некоторые сервера с API в сети все еще используют протокол OAuth 1.0a. Реализация его для программистов 1С представляет немалые трудности. А иногда в запросах еще используются параметры, и вот с ними совсем беда.

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

Наименование Файл Версия Размер
Особенности реализации доступа по протоколу OAuth 1.0a в случае, если в запросе есть параметры:
.epf 9,30Kb
4
.epf 9,30Kb 4 Скачать

Для реализации доступа по протоколу  OAuth 1.0a нужно :

1)Получить на сайте у поставщика данных ключ и "секретный ключ" - наборы символов.

2)Пользуясь инструкцией с того же сайта (инструкция должна быть, если они не совсем отмороженные), получить токен и "секретный токен". 

3)Используя эти 4 набора символов для аутентификации, вызывать необходимые методы и получать данные, добавляя в заголовок запроса OAuth сигнатуру, рассчитанную по методу, например, HMAC-SHA1 (требования конкретного сайта, метод может быть другим)

 

Первые 2 пункта в этой публикации не рассматриваются. В публикации //infostart.ru/1c/articles/671523/ п.2 предлагается реализовать в 1с программно. Я считаю, что это лишнее. Можно (по инструкции), используя свободное приложение для тестирования API, например postman (https://www.postman.com), получить токены, сохранить и использовать всю жизнь. Зачем писать код для 1 раза?

Пример вызова методов, в случае, когда токены уже получены, есть в //infostart.ru/public/235861/ (для твиттера). Я использовал обработку оттуда как образец. В одной из функций есть пример вызова метода POST с параметрами , но на эту ветку алгоритм на самом деле не попадает. Когда я попытался написать свой вызов по аналогии, получился "забавный" результат:

Метод GET без параметров, например : http://b2b.cifrotech.ua/api/rest/products - работает.

Метод с параметром : http://b2b.cifrotech.ua/api/rest/products?limit=1 - работает.

Метод с любым другим параметром, например : http://b2b.cifrotech.ua/api/rest/products?sku=1

или с 2 параметрами : http://b2b.cifrotech.ua/api/rest/products?limit=1&page1

НЕ РАБОТАЕТ! Выдает "неверная сигнатура".

Как такое может быть ? Ведь алгоритм составления подписи не зависит от символов в параметрах ?????

Методом тыка и мата был найден ответ :

Параметр limit и все остальные обрабатываются по-разному! И это не заморочки конкретного сайта, т.к. тот же postman ничего не знает про сайт, он просто реализует протокол. Параметр limit при конкатенации строки для вычисления сигнатуры ставится в начале, а остальные - в конце. И это НИГДЕ не записано!
Тестовую обработку с примерами методов прилагаю (подставьте свои сервер и ресурс, если https, то не забудьте исправить конструктор HTTPСоединение)
По сравнению с //infostart.ru/1c/articles/671523/ я добавил расчет сигнатуры прямо в 1с , без вызова функции на java.

Тестировалось на 1с 8.3.13. Конфигурация не имеет значения, это просто тест.

OAuth 1.0a API

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    15936    13    18    

13

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17891    6    15    

12

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88948    163    216    

318

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25874    9    0    

7

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16480    42    49    

23
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Syeriy 02.09.21 15:40 Сейчас в теме
Здравствуйте, можете, пожалуйста, выложить листинг обработки?
2. bulpi 215 02.09.21 18:59 Сейчас в теме
(1)

Процедура КнопкаВыполнитьНажатие(Кнопка)
	//без параметров
	Стр=ПолучитьРезультатЗапросаАпиOAuth10a(OAuthConsumerKey,OAuthConsumerSecret,OAuthToken,OAuthSecret,"b2b.cifrotech.ua","/api/rest/products","","");
	Сообщить(Стр);
	//параметр limit
	Стр=ПолучитьРезультатЗапросаАпиOAuth10a(OAuthConsumerKey,OAuthConsumerSecret,OAuthToken,OAuthSecret,"b2b.cifrotech.ua","/api/rest/products","limit=1","");
	Сообщить(Стр);
	//параметр limit и еще 1
	Стр=ПолучитьРезультатЗапросаАпиOAuth10a(OAuthConsumerKey,OAuthConsumerSecret,OAuthToken,OAuthSecret,"b2b.cifrotech.ua","/api/rest/products","limit=1","page=1");
	Сообщить(Стр);
	//параметр НЕ limit 
	Стр=ПолучитьРезультатЗапросаАпиOAuth10a(OAuthConsumerKey,OAuthConsumerSecret,OAuthToken,OAuthSecret,"b2b.cifrotech.ua","/api/rest/products","sku=1","");
	Сообщить(Стр);
	
КонецПроцедуры


Функция ПолучитьРезультатЗапросаАпиOAuth10a(oauth_consumer_key,oauth_consumer_secret,oauth_token,oauth_token_secret,Сервер,АдресРесурса,ПараметрЛимит,ОстальныеПараметры)
	Параметры="";
	Если Не ПустаяСтрока(ПараметрЛимит) Тогда
		Параметры=Параметры+"?"+ПараметрЛимит;
		Если Не ПустаяСтрока(ОстальныеПараметры) Тогда
			Параметры=Параметры+"&"+ОстальныеПараметры;
		КонецЕсли;
	ИначеЕсли Не ПустаяСтрока(ОстальныеПараметры) Тогда	
		Параметры=Параметры+"?"+ОстальныеПараметры;
	КонецЕсли;	
	ЗапросHTTP=Новый HTTPЗапрос();
	ЗапросHTTP.АдресРесурса=АдресРесурса+Параметры; //
	
	oauth_signature_method="HMAC-SHA1";
	oauth_timestamp=Формат(ТекущаяУниверсальнаяДата()-'19700101',"ЧГ=");
	oauth_nonce=oauth_timestamp;
	oauth_version="1.0";
	oauth_signature_base="GET&"
	+КодироватьСтроку("http://"+Сервер+АдресРесурса,СпособКодированияСтроки.КодировкаURL)+"&" 
	+КодироватьСтроку(""
	+?(ПустаяСтрока(ПараметрЛимит),"",ПараметрЛимит+"&")
	+"oauth_consumer_key="+oauth_consumer_key+"&"
	+"oauth_nonce="+oauth_nonce+"&"
	+"oauth_signature_method="+oauth_signature_method+"&"
	+"oauth_timestamp="+oauth_timestamp+"&"
	+"oauth_token="+oauth_token+"&"
	+"oauth_version="+oauth_version
	+?(ПустаяСтрока(ОстальныеПараметры),"","&"+ОстальныеПараметры)
	,СпособКодированияСтроки.КодировкаURL);
	
	hmac_sha1_secret=oauth_consumer_secret+"&"+oauth_token_secre­t;
	oauth_signature=КодироватьСтроку(ПолучитьСигнатуру(hmac_sha1_secret,oauth_signature_base,"SHA1"),СпособКодированияСтроки.КодировкаURL);
	ЗапросHTTP.Заголовки.Вставить("Authorization","OAuth "
	+"oauth_consumer_key="""+oauth_consumer_key+""", "
	+"oauth_token="""+oauth_token+""", "
	+"oauth_signature_method="""+oauth_signature_method+""", "
	+"oauth_timestamp="""+oauth_timestamp+""", "
	+"oauth_nonce="""+oauth_nonce+""", "
	+"oauth_version="""+oauth_version+""", "
	+"oauth_signature="""+oauth_signature+"""");
	HTTP=Новый HTTPСоединение(Сервер);
	HTTPОтв=HTTP.Получить(ЗапросHTTP);
	Возврат HTTPОтв.ПолучитьТелоКакСтроку();
КонецФункции

//Дальше процедуры, реализующие сигнатуру
Функция ПолучитьСигнатуру(Знач Key, Знач Text,Знач  HashFunction="SHA256") Экспорт
	
	//Преобразуем ключ в hex
	kKey = "";
	Для к = 1 ПО СтрДлина(Key) Цикл
		
		kKey = kKey + ПреобразоватьДесятичнуюСИВHex(КодСимвола(Сред(Key,к,1)));
		
	КонецЦикла; 
	
	Result = HMAC(kKey, Text, HashFunction);
ТипДвоичныеДанные = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary"); 
ДвоичныеДанныеXDTO = ФабрикаXDTO.Создать(ТипДвоичныеДанные,Result); 
ТипДвоичныеДанныеBase64 = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "base64Binary");
 Result64= ФабрикаXDTO.Создать(ТипДвоичныеДанныеBase64, ДвоичныеДанныеXDTO.Значение).ЛексическоеЗначение;
	Возврат Result64;
КонецФункции


// Функция - HMAC
//
// Параметры:                            1
//  K     - ключ    в шестнадцатеричном виде - Строка
//  text - текстовое сообщение - Строка
//  Hash - Hash function (CRC32, MD5, SHA1, SHA256) - Строка
// Возвращаемое значение:
//     строка HMAC - Строка
Функция HMAC(Знач K, Знач text, Знач Hash)
	
	Перем kResult;
	Перем К0;
	
	//Если длина ключа K больше размера блока, то к ключу K применяем хэш-функцию
	Если СтрДлина(K)>128 Тогда 
		K = SHA1(K,Hash);
	КонецЕсли;	
	
	//1 Дополняем ключ K нулевыми байтами до размера блока. Размер блока хэш-функции SHA-1 равен 64 байтам.
	StringSHA1 = Лев(K,128);
	Для к = СтрДлина(K) По 128 Цикл
		StringSHA1 = StringSHA1 + "0";
	КонецЦикла;
	К0 = StringSHA1;
	
	//2 Выполняем операцию «побитовое исключающее ИЛИ» c константой 0x36.
	b = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ("36"));
	
	к = 1;
	Пока к < 128 Цикл
		a             = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ(Сред(StringSHA1,к,2)));
		с             = XOR(a,b);        
		StringSHA1     = Лев(StringSHA1,к-1)+с+Прав(StringSHA1, 128-к);
		к             = к + 2;
	КонецЦикла;
	
	StringSHA1 = Лев(StringSHA1,128);
	
	//3 Выполняем склейку исходного сообщения со строкой, полученной на шаге 2.
	Для к = 1 По СтрДлина(text) Цикл
		
		StringSHA1 = StringSHA1 + ПреобразоватьДесятичнуюСИВHex(КодСимвола(Сред(text,к,1)));
		
	КонецЦикла;
	
	//4 Применим хэш-функцию SHA-1 к строке, полученной на прошлом шаге.
	StringSHA1     = SHA1(StringSHA1,Hash);
	kResult     = StringSHA1;
	
	//5 Выполним операцию «побитовое исключающее ИЛИ» c константой 0x5c.
	StringSHA1 = К0;
	
	b = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ("5c"));
	
	к = 1;
	Пока к < 128 Цикл
		a             = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ(Сред(StringSHA1,к,2)));
		с             = XOR(a,b);        
		StringSHA1     = Лев(StringSHA1,к-1)+с+Прав(StringSHA1, 128-к);
		к             = к + 2;
	КонецЦикла;
	
	StringSHA1 = Лев(StringSHA1,128);
	
	//6 Склейка строки, полученной на шаге 4, со строкой, полученной на шаге 5.
	StringSHA1 = StringSHA1 + kResult;
	
	//7 Применим хэш-функцию SHA-1 к строке, полученной на прошлом шаге.
	StringSHA1 = SHA1(StringSHA1,Hash);    
	
	Возврат StringSHA1;
	
КонецФункции

Функция SHA1(Знач nString, Hash)    
	Хеширование        = Новый ХешированиеДанных(ХешФункция[Hash]);
	ТипhexBinary    = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary");
	ДвоичныеДанные    = ФабрикаXDTO.Создать(ТипhexBinary,nString);
	Хеширование.Добавить(ДвоичныеДанные.Значение);    
	sign             = Хеширование.ХешСумма;
	sign 			 = СтрЗаменить(НРЕГ(sign), " ", "");
	Возврат СтрЗаменить(НРЕГ(sign), " ", "");
КонецФункции

Функция ПреобразоватьДесятичнуюСИВHex(Знач int)	
	Если int < 256 Тогда 
		Возврат Прав("00" + ПреобразоватьДесятичнуюСИВОднобайтовыйHex(int),2);
	Иначе
		Возврат Прав("0000" + ПреобразоватьДесятичнуюСИВДвухбайтовыйHex(int),4);
	КонецЕсли;                                 	
КонецФункции

Функция ПреобразоватьHexВДесятичнуюСИ(Знач hex)
	simbol     = СтрДлина(hex) - 1;
	dec     = 0;
	i         = 1;
	Пока simbol >= 0 Цикл
		simbolHex     = Сред(hex, i, 1);
		Res         = Найти("0123456789abcdef", simbolHex) - 1;
		dec         = dec + Res * Pow(16, simbol);
		simbol         = simbol - 1;
		i             = i + 1;
	КонецЦикла;   
	Возврат dec;
КонецФункции

Функция ПреобразоватьЧислоВДвоичнуюСИ(Знач int, rBit = 8)
	b = "";
	Для k = 1 По rBit Цикл
		m     = pow(2, rBit - k);
		bit = Цел(int / m);
		int = int - m * bit;
		b     = b + bit;
	КонецЦикла;                                
	Возврат b;                                     
КонецФункции

Функция XOR(a, b)    
	res = 0;
	s     = 1;
	к     = Мин(СтрДлина(a), СтрДлина(b));    
	Пока к > 0 Цикл        
		a1     = Сред(a,к,1);
		b1     = Сред(b,к,1);                     
		res = res + s * ?(a1=b1,0,Макс(a1,b1));
		s     = s*2;        
		к     = к-1;        
	КонецЦикла;     
	Возврат ПреобразоватьДесятичнуюСИВHex(res);
КонецФункции

Функция ПреобразоватьДесятичнуюСИВДвухбайтовыйHex(Знач int)	
	BinaryData = ПреобразоватьЧислоВДвоичнуюСИ(int, 11);	
	BinaryData = "110" + Лев(BinaryData,5) + "10" + Прав(BinaryData, 6);	
	DecimalData = ПолучитьДесятичноеЧислоИзДвоичного(BinaryData);	
	HexData = ПреобразоватьДесятичнуюСИВОднобайтовыйHex(DecimalData);	
	Возврат HexData;                                        	
КонецФункции

Функция ПолучитьДесятичноеЧислоИзДвоичного(b)	
	res 	= 0;
	s     	= 1;
	к     	= СтрДлина(b);
	Пока к > 0 Цикл        
		bit   = Сред(b,к,1);
		res = res + s * bit;
		s   = s*2;        
		к   = к-1;        
	КонецЦикла;                              	
	Возврат res;                             	
КонецФункции

Функция ПреобразоватьДесятичнуюСИВОднобайтовыйHex(Знач int)	
	hex = "";
	Пока int <> 0 Цикл
		p   = int % 16;
		hex = Сред("0123456789abcdef", p + 1, 1) + hex;
		int = Цел(int / 16);
	КонецЦикла;
	Возврат hex;                                           	
КонецФункции
Показать
3. Syeriy 03.09.21 12:34 Сейчас в теме
Оставьте свое сообщение