Аутентификация на внешних сервисах посредством OAuth

Пример подключения к сервисам Google из 1С с помощью протокола OAuth и получения данных с внешнего сервиса.

 В данной  статье на примере подключения к сервисам Google я продемонстрирую реализацию подключения к сервисам Google при помощи аутентификации по протоколу OAuth 2.0 на языке программирования 1С.  В статье будет показана реализация подключения к сервису календарей Google с помощью авторизации по протоколу OAuth 2.0. Получение списка календарей и загрузка событий календаря на форму.

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

OAuth — открытый протокол (схема) авторизации, который позволяет предоставить третьей стороне ограниченный доступ к защищённым ресурсам пользователя без необходимости передавать ей (третьей стороне) логин и пароль(ru.wikipedia.org/wiki/OAuth). Суть такого вида аутентификации является отсутствие необходимости передавать логин и пароль к персональным данным или регистрироваться на сервисе проходя нудную процедуру регистрации затем хранить пароли от разных аккаунтов, да и сервисам полегче не нужно создавать системы хранения учётных данных и ещё и отвечать за их возможную утечку. Пользователь может быть уверен что приложению будет доступен только тот набор данных которые он разрешил.  Также можно гарантировать что приложение будет продолжать работать пока пользователь не запретит ему доступ к своим данным, при этом пользователь может менять пароль и это никак не скажется на работе приложения. После получения доступа приложение может работать не требуя от пользователя подтверждения своих привилегий доступа (хотя у сервисов предоставляющих доступ есть свои ньюансы на этот счёт).

Итак как работает этот протокол аутентификации. В стандарте описана несколько схем работы протокола на все случаи жизни от авторизации на Web серверах до аутентификации на Smart-телевизорах. Жаждущие подробносей могут углубиться в чтение на https://www.digitalocean.com/community/tutorials/oauth-2-ru. В статье я не буду подробно останавливаться на деталях и особенностях этого протокола. В статье будет описан только наиболее часто используемый способ авторизации — получение токена доступа через код авторизации.

Итак аутентификация состоит из трёх последовательных этапов и одного предварительного связанного с регистрацией 1С обработки в качестве приложения на сервисах Google. Для приложения мы активируем API для тех типов данных, доступ к которым нам понадобится для приложения, ещё в приложении мы создадим OAuth идентификатор нашего приложения.

Начнем с предварительного этапа, регистрации приложения.

Нам потребуетя войти в консоль Google Api с действующей учетной записи Google по ссылке https://console.developers.google.com/apis/dashboard.

Создадим проект.

 

 

Следующим шагом нам нужно определиться какие API Google мы будем использовать, их надо активировать. Сделать это можно перейдя кликнув на ссылке перейти к обзору API ниже на рисунке. Для наших целей достаточно Calendar API.

 

 

 

Осталось создать идентификатор учётных данных OAuth. На картинке жмем Учётные данные,
Теперь создаём идентификатор OAuth

 

 


 

 

Далее открывается вот такое модальное окно, в котором Google предлагает нам настроить окно подтверждения пользователем доступа к их данным. Это то самое окно в котором вы даёте согласие на доступ к своим учётным данным. Настроим, жмём на Set up Consent Screen.

Здесь нас интересуют области действия для API Google. Это те разрешения на доступ к персональным данным которые мы будем просить у пользователя. Для примера достаточно прав чтения данных календаря (read only).  В нашем примере нам нужны такие права
 

 

 

 

 

Нажимаем сохранить. И переходим в учетные данные для создания идентификатора OAuth.

 

 

Итак, с консолью Google мы закончили. Для удобства можно скачать файл JSON. В нём содержатся все требуемые данные которые потребуются нам в дальнейшем.
Пора заняться подключением из 1С.
И это только предварительный этап😊.

 

Этапы авторизации будут располагаться совместно с их реализацией в обработки. Сама обработка будет состоять из двух форм, первая основная на которой будут отображаться получаемые данные и вспомогательная, служащая в качестве встроенного web-браузера для отображения веб страницы пользователю, в которой он сможет разрешить для нашего приложения доступ к своим данным.доступ к пользовательским данным. Поле в котором будет отображаться страница имеет вид полеHTMLДокумент

Версия платформы на которой тестировалась обработка 8.3.14, в которой, наконец-то, был заменен веб-движок с престарелой версией Internet Explorer на современный WebKit. Что само по себе открывает огромные возможности по взаимодействию с интернетом из 1С.

 

 

Первый этап.  1.    Обращение к авторизационному серверу за разрешением пользовательских данных. Авторизационный сервер это сервис который хранит пользовательские данные и предоставляет доступ к пользовательским данным. На этом этапе формируется GET запрос со следующими параметрами

client_id — идентификатор нашего приложения

redirect_uri — веб-страница на которую вы будете переадресованы после того как пользователь разрешил доступ к своим данным

scope  — это области пользовательских данных, на которые мы будем просить разрешения у пользователя. Помните мы настраивали их в окне аутентификации. Задаются в качестве текстовой строки через пробел.

response_type — тип возвращаемого кода,задаётся как code, и означает вернуть аутентификационный код  в параметрах запроса при переадресации на страницу redirect_uri, после того  как пользователь нажмёт разрешить на доступ к своим данным.

Есть также и другие параметры но значение по умолчанию этих параметров нас вполне устраивает, подробнее можно почитать здесь(англ.)

Кнопка Авторизация  содержит код начала процесса авторизации

&НаКлиенте
Процедура Авторизоваться(ОписаниеДействия = Неопределено)

ПараметрыФормы = новый структура("Адрес", АдресСтраницыАутентификации());
ОО = Новый ОписаниеОповещения("ОбработатьAccessToken", ЭтаФорма, ОписаниеДействия);
ОткрытьФорму("ВнешняяОбработка.АутентификацияGoogle.Форма.ФормаАутентификации", ПараметрыФормы, Элементы.Авторизоваться, ,,,ОО, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

 Мы просто открываем вспомогательную форму авторизацию с одним параметром — адресом страницы аутентификации, который формирует для нас функция:

&НаКлиентеНаСервереБезКонтекста
Функция АдресСтраницыАутентификации()

ПараметрыURL = Новый Структура;
Адрес = "https://accounts.google.com/o/oauth2/v2/auth";
ПараметрыURL.Вставить("client_id", "<ваш уникальный идентификатор приложения из Google API console>.apps.googleusercontent.com");
ПараметрыURL.Вставить("redirect_uri", "http://localhost");
ПараметрыURL.Вставить("scope", "https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.readonly  https://www.googleapis.com/auth/calendar");
ПараметрыURL.Вставить("response_type", "code");
ПараметрыURL.Вставить("prompt", "consent"); //Пользователю отображается только окно разрешения доступа к его пользовательским данным
Возврат Адрес(Адрес, ПараметрыURL);

КонецФункции // ПолучитьAuthToken()

В результате работы кода кнопки открывается окно аутентификации. После того как пользователь нажал кнопку Allow(разрешить), сервер Google перенаправит нас на страницу указанную при регистрации приложения — http://localhost, которая попытается открыться в том же поле HTML Документа, но скорее всего не сможет, если у вас не запущен локальный веб-сервер. В обработчике события поля HTML документа мы извлечём полученный код аутентификации.

Ниже показан код формы, в котором нам нужно извлечь аутентификационный код из параметров командной строки, так как 1С не предоставляет возможности в случае localhost обработать параметры адресной строки(напишите в комментариях, если существует способ), но отображает адрес страницы редиректа в теле полеHTML документа, то код извлекаем из тела страницы.
 


&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)

Адрес = Элемент.Документ.URL;
if Адрес = "about:blank" Then
InnerHTML = Элемент.Документ.body.InnerHTML;
AuthCode = AuthCode(InnerHTML);
Закрыть(AuthCode);
endif

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

&НаКлиентеНаСервереБезКонтекста
Функция AuthCode(URL)
НачалоКода = СтрНайти(ВРЕГ(URL), ВРЕГ("code="), НаправлениеПоиска.СНачала);
Если НачалоКода = 0 Тогда
Возврат "";
КонецЕсли;
НачалоКода = НачалоКода + 5;
КонецКода = СтрНайти(ВРЕГ(URL), ВРЕГ("&amp;"), НаправлениеПоиска.СНачала, НачалоКода);
Возврат Сред(URL, НачалоКода, КонецКода - НачалоКода);
КонецФункции

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Адрес = Параметры.Адрес;
КонецПроцедуры




На основную форму возвращаем код аутентификации который позволит нам обменять его на токен доступа на следующем этапе еще одним запросом к серверу.

Второй этап. Полученный код следует обменять на токен доступа(Access token). Токен доступа это идентификатор который выдаётся авторизационным сервером приложению на определенный промежуток времени для доступа к данным пользователя. Запрос выполняется методом POST со следующими параметрами.

code — полученный авторизационный код

client_id — идентификатор приложения из Console APi Goolge

client_secret — секретный код приложения из Console APi Google

redirect_uri — адрес переадресации указанный в Console APi Google

grant_type — содержит значение authorization_code

&НаКлиенте
Процедура ОбработатьAccessToken(AuthCode, ОписаниеДействия) Экспорт

Если AuthCode <> Неопределено И Не ПустаяСтрока(AuthCode) Тогда
Tokens = Tokens(AuthCode);
AccessToken = AccessToken(Tokens);
RefreshToken = ?(RefreshToken(Tokens) = Неопределено, RefreshToken, RefreshToken(Tokens));
Календари = ЗаполнитьКалендари(AccessToken);
ЗаполнитьКалендариНаФорме(Календари);
ПоказатьОповещениеПользователя("Авторизация успешна",,,,СтатусОповещенияПользователя.Информация);
Если ОписаниеДействия <> Неопределено Тогда
СтрокаВыполнить = ОписаниеДействия.Действие + "(" + AccessToken + "," + ОписаниеДействия.ПараметрыДействия + ")";
Выполнить(СтрокаВыполнить);
КонецЕсли;
Иначе
AccessToken = "";
КонецЕсли;

КонецПроцедуры // ОбработатьAccessToken()

&НаКлиентеНаСервереБезКонтекста
Функция AccessToken(Tokens)

Если типЗнч(Tokens ) = Тип("Структура") Тогда
Возврат Tokens.access_token;
Иначе
Возврат Неопределено;
КонецЕсли;

КонецФункции // AccessToken()

&НаКлиентеНаСервереБезКонтекста
Функция RefreshToken(Tokens)

Если Tokens.Свойство("refresh_token") Тогда
Возврат Tokens.refresh_token;
Иначе
Возврат Неопределено;
КонецЕсли;

КонецФункции // RefreshToken()

&НаСервереБезКонтекста
Функция Tokens(AuthCode)

ПараметрыURL = Новый Структура;
АдресЗапроса = "https://www.googleapis.com/oauth2/v4/token";
ПараметрыURL.Вставить("client_id", "<ваш идентификатор приложения из Google API Console>.apps.googleusercontent.com");
ПараметрыURL.Вставить("redirect_uri", "http://localhost");
ПараметрыURL.Вставить("code", AuthCode);
ПараметрыURL.Вставить("client_secret", "<ваш secret key>");
ПараметрыURL.Вставить("grant_type", "authorization_code");

АдресЗапроса = Адрес(АдресЗапроса, ПараметрыURL);
СтруктураURI = СтруктураURI(АдресЗапроса);
HTTPСоединение = новый HTTPСоединение(СтруктураURI.Хост,443 , , ,, 15, Новый ЗащищенноеСоединениеOpenSSL);
headers = Новый Соответствие;
headers.Вставить("User-Agent", "Mozilla");
headers.Вставить("Host", СтруктураURI.Хост);
headers.Вставить("Content-Type", "application/x-www-form-urlencoded");
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере, headers);
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON = новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ);
Token = ПрочитатьJSON(ЧтениеJSON, Ложь);
Возврат Token;
Иначе
ВызватьИсключение "Произошла ошибка обращения к серверу," + "Токен не получен" +
Символы.ПС + "Статус ответа сервера: " + HTTPОтвет.КодСостояния;
КонецЕсли;

КонецФункции
&НаСервереБезКонтекста
Функция Адрес(Знач URL, Знач ПараметрыURL)

Перем МассивПараметров;
МассивПараметров = Новый Массив;
Для каждого Параметр Из ПараметрыURL Цикл
МассивПараметров.Добавить(Параметр.Ключ + "=" + Параметр.Значение);
КонецЦикла;
URL = СокрП(URL);
URL = ?(СтрЗаканчиваетсяНа(URL, "/"), URL, URL + "/");
Возврат URL + "?" + КодироватьСтроку(СтрСоединить(МассивПараметров, "&"), СпособКодированияСтроки.URLВКодировкеURL);

КонецФункции

В коде отправляем подготовленный POST-запрос и в случае успешного результата, получаем JSON ответ с токеном доступа(access token) и токеном обновления, который мы можем использовать при повторном запросе токена доступа когда действующий токен доступа истечёт.

На этом авторизация завершена, пришло время воспользоваться пройденной авторизацией и получить что-нибудь полезное.

Третий этап.

Имея токен доступа в получим список календарей и события выбранного календаря.

&НаКлиенте
Процедура ЗаполнитьКалендариНаФорме(Календари)

Элементы.КалендариGoogle.СписокВыбора.Очистить();
Если Календари.items.Количество() > 0 Тогда
Для Каждого Календарь Из Календари.items Цикл
Элемент = Элементы.КалендариGoogle.СписокВыбора.Добавить(Календарь.id, Календарь.summary);
КонецЦикла;
КалендариGoogle = Элементы.КалендариGoogle.СписокВыбора.Получить(0).Значение;
КалендариGoogleПриИзменении(Неопределено);
КонецЕсли;

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

Функция ЗаполнитьКалендари(AccessToken)

Возврат ПолучитьСписокКалендарей(AccessToken);

КонецФункции

Функция ПолучитьСписокКалендарей(AccessToken)

ПараметрыURL = Новый Структура;
АдресЗапроса = "https://www.googleapis.com/calendar/v3/users/me/calendarList";

СтруктураURI = СтруктураURI(АдресЗапроса);
HTTPСоединение = новый HTTPСоединение(СтруктураURI.Хост,443 , , ,, 15, Новый ЗащищенноеСоединениеOpenSSL);
headers = Новый Соответствие;
headers.Вставить("User-Agent", "Mozilla");
headers.Вставить("Host", "www.googleapis.com");
headers.Вставить("Content-Type", "application/x-www-form-urlencoded");
headers.Вставить("Authorization", "Bearer " + AccessToken);
headers.Вставить("Accept", "application/json");
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере, headers);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON = новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ);
Календари = ПрочитатьJSON(ЧтениеJSON, ЛОжь);
Возврат Календари;
Иначе
ВызватьИсключение "Произошла ошибка обращения к серверу," + "Токен не получен" +
Символы.ПС + "Статус ответа сервера: " + HTTPОтвет.КодСостояния;
КонецЕсли;

КонецФункции

&НаКлиенте
Функция ПолучитьСписокСобытий(Знач AccessToken,Знач ИдКалендаря)

ПараметрыURL = Новый Структура;
АдресЗапроса = "https://www.googleapis.com/calendar/v3/calendars/{ИдКалендаря}/events";
ИдКалендаря = КодироватьURI(ИдКалендаря);
АдресЗапроса = СтрЗаменить(АдресЗапроса, "{ИдКалендаря}", ИдКалендаря);
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("key", "<Секретный ключ клиента>");

АдресЗапроса = Адрес(АдресЗапроса, ПараметрыURL);

СтруктураURI = СтруктураURI(АдресЗапроса);
HTTPСоединение = новый HTTPСоединение(СтруктураURI.Хост,443 , , ,, 15, Новый ЗащищенноеСоединениеOpenSSL);
headers = Новый Соответствие;
headers.Вставить("Host", СтруктураURI.Хост);
headers.Вставить("Content-Type", "application/x-www-form-urlencoded");
headers.Вставить("Authorization", "Bearer " + AccessToken);
headers.Вставить("Content-length", "0");
headers.Вставить("Accept", "application/json");
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере, headers);
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON = новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ);
СобытияКалендаря = ПрочитатьJSON(ЧтениеJSON, Истина);
Возврат СобытияКалендаря;
ИначеЕсли HTTPОтвет.КодСостояния = 401 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(HTTPОтвет.ПолучитьТелоКакСтроку());
ОтветJSON = ПрочитатьJSON(ЧтениеJSON, ЛОЖЬ);
Если ОтветJSON.error.message = "Invalid Credentials" Тогда
//Обновить Token
AccessToken = AccessToken(ОбновитьТокен(RefreshToken));
Если ЗначениеЗаполнено(AccessToken) Тогда
Возврат ПолучитьСписокСобытий(AccessToken, ИдКалендаря);
Иначе
ПоказатьОповещениеПользователя("Необходима авторизация",,,,СтатусОповещенияПользователя.Информация);
ПараметрыДействия = Новый Массив;
ПараметрыДействия.Добавить(ИдКалендаря);
Авторизоваться(ОписаниеДействия("ПолучитьСписокСобытий", ПараметрыДействия));
КонецЕсли;
КонецЕсли;

КонецЕсли;


КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ОбновитьТокен(RefreshToken)

Если Не ПустаяСтрока(RefreshToken) Тогда
Возврат RefreshTokens(RefreshToken);
Иначе
Возврат Неопределено;
КонецЕсли;

КонецФункции

&НаСервереБезКонтекста
Функция RefreshTokens(RefreshToken)

ПараметрыURL = Новый Структура;
АдресЗапроса = "https://www.googleapis.com/oauth2/v4/token";
ПараметрыURL.Вставить("client_id", "<идентификатор приложения>.apps.googleusercontent.com");
ПараметрыURL.Вставить("redirect_uri", "http://localhost");
ПараметрыURL.Вставить("refresh_token", RefreshToken);
ПараметрыURL.Вставить("client_secret", "<секретный ключ>");
ПараметрыURL.Вставить("grant_type", "refresh_token");

АдресЗапроса = Адрес(АдресЗапроса, ПараметрыURL);
СтруктураURI = СтруктураURI(АдресЗапроса);
HTTPСоединение = новый HTTPСоединение(СтруктураURI.Хост,443 , , ,, 15, Новый ЗащищенноеСоединениеOpenSSL);
headers = Новый Соответствие;
headers.Вставить("User-Agent", "Mozilla");//google-oauth-playground
headers.Вставить("Host", СтруктураURI.Хост);
headers.Вставить("Content-Type", "application/x-www-form-urlencoded");
HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере, headers);
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON = новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ);
Token = ПрочитатьJSON(ЧтениеJSON, Ложь);
Возврат Token;
Иначе
ВызватьИсключение "Произошла ошибка обращения к серверу," + "Токен не получен" +
Символы.ПС + "Статус ответа сервера: " + HTTPОтвет.КодСостояния;
КонецЕсли;

КонецФункции

&НаКлиенте
Процедура КалендариGoogleПриИзменении(Элемент)

ИдКалендаря = Элементы.КалендариGoogle.СписокВыбора.НайтиПоЗначению(КалендариGoogle);
СписокСобытий = ПолучитьСписокСобытий(AccessToken, ИдКалендаря.Значение) ;
События.Очистить();
Если События = Неопределено Тогда
Возврат;
Конецесли;
Для каждого Событие Из СписокСобытий["items"] Цикл

Если Событие["start"] ["date"] = Неопределено Тогда
ДатаСобытия = '00010101';
Иначе
ДатаСобытия = ПрочитатьДатуJSON(Событие["start"] ["date"], ФорматДатыJSON.ISO);
КонецЕсли;
Если Событие["summary"] = Неопределено Тогда
ОписаниеСобытия = "";
Иначе
ОписаниеСобытия =  Событие["summary"];
КонецЕсли;
События.Добавить(ДатаСобытия, ОписаниеСобытия + "("  + Формат(ДатаСобытия, "ДФ=dd.MM.yy") + ")");

КонецЦикла;
КонецПроцедуры

В коде мы формируем пару GET запросов на получение календарей и событий календаря, адреса на которые отправляются запросы определены в документации Google, применительно к API календаря подробнее ознакомиться можно по ссылке здесь(англ.). Обратите особое внимание на заголовок Bearer в запросах в нем мы передаём наш токен доступа. Обязателен также задать заголовок Content-type как в примере. Остальные параметры упоминались ранее.

Стоит прокомментировать этот участок кода, здесь анализируем код ответа. Если в результате запроса получили ошибку "Invalid Credentials", это означает что наш текущий токен доступа истёк, и тогда есть два варианта, или получить новый токен доступа повторно с помощью токена обновления (Refresh token) или запросить у пользователя повторно доступ к его данным через окно авторизации.

Если HTTPОтвет.КодСостояния = 200 Тогда
Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
ЧтениеJSON = новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ);
СобытияКалендаря = ПрочитатьJSON(ЧтениеJSON, Истина);
Возврат СобытияКалендаря;
ИначеЕсли HTTPОтвет.КодСостояния = 401 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(HTTPОтвет.ПолучитьТелоКакСтроку());
ОтветJSON = ПрочитатьJSON(ЧтениеJSON, ЛОЖЬ);
Если ОтветJSON.error.message = "Invalid Credentials" Тогда
//Обновить Token
AccessToken = AccessToken(ОбновитьТокен(RefreshToken));
Если ЗначениеЗаполнено(AccessToken) Тогда
Возврат ПолучитьСписокСобытий(AccessToken, ИдКалендаря);
Иначе
ПоказатьОповещениеПользователя("Необходима авторизация",,,,СтатусОповещенияПользователя.Информация);
ПараметрыДействия = Новый Массив;
ПараметрыДействия.Добавить(ИдКалендаря);
Авторизоваться(ОписаниеДействия("ПолучитьСписокСобытий", ПараметрыДействия));
КонецЕсли;
КонецЕсли;
//ВызватьИсключение "Произошла ошибка обращения к серверу," + "Токен не получен" +
//Символы.ПС + "Статус ответа сервера: " + HTTPОтвет.КодСостояния;
Сообщить(HTTPОтвет.ПолучитьТелоКакСтроку());
Сообщить(AccessToken);
КонецЕсли;





R03;

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

 

 

К статье прикреплена обработка содержащая полный код описанной в статье обработки. Из обработки удалены зарегистированные мной идентификаторы приложения, перед запуском вам нужно будет зарегистрировать собственное приложение в Google API.

Спасибо за внимание.

6 Comments

  1. binx

    (1)

    Слишком много действий, только для того чтобы авторизоваться.

    Что поделать, таков протокол.

    Эта схема только для гугла?

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

    не понял насчет «структуры», напишите на каком этапе у вас не получается. Что за структура?

    Вроде бы в 1С давно реализована возможность синхронизации с акк гугла, или ошибаюсь?

    Думаю что вы ошибаетесь, Синтаксис помощнике нет функций подключения к Google или к какому либо другому подобному сервису.

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

    OAuth 2.0 опубликован в 2012 году и насколько мне известно, это последняя редакция этого протокола

    Reply
  2. uno-c

    (2)

    Думаю что вы ошибаетесь, Синтаксис помощнике нет функций подключения к Google или к какому либо другому подобному сервису

    Сейчас под рукой, например, Бухгалтерия предприятия, редакция 3.0.70.30. В ней есть общий модуль СинхронизацияСКалендаремGoogle — там тоже трехногая авторизация используется с помощью идентификатора клиента oAuth. И прямо в коде, кстати, client_id и client_secret, одни на всю страну )

    Reply
  3. binx

    Спасибо за комментарий, надо посмотреть.

    Reply
  4. fixin

    Большое человеческое спасибо.

    Использовал для доступа к accounts.zoho.com

    Долго тупил по поводу ошибки 301 на получении Refresh токена, только потом скопировал 1:1 и понял, что стучался на HTTP, а не на HTTPS.

    Спасибо.

    Reply
  5. fixin

    (3) гм, а где взять этот ключ сервисного аккаунта? Не для Google? Это поддерживается в протоколе?

    Reply
  6. uno-c

    (7)В протоколе поддерживается несколько методов создания подписей: https://ru.wikipedia.org/wiki/OAuth#Методы_создания_подписей

    Гугл в своей 2LO («двуногая авторизация») выбрал RSA-SHA, соответственно Гугл создал возможность сгенерировать/скачать закрытый ключ для сервис-аккаунта.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *