Имя: Пароль:
1C
1С v8
WinHttp: HTTPS не работает
0 queit
 
15.02.13
10:01
Пытаюсь связать 1с и google calendar.
Загуглил статью: http://pro1c.net/tips/Авторизация-oauth-20-из-1С-82/#respond
Первый этап авторизации проходит на ура, а вот второй совсем никак.
Отправляю запрос на сервер, формирую так:

   ХТТПЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
   Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
   Скрипт.language="javascript";
   Скрипт.AddObject("ХТТПЗапрос",ХТТПЗапрос);
   Скрипт.Eval("ХТТПЗапрос.Option(4)=13056");
   
   ХТТПЗапрос.Open("POST", "https://accounts.google.com/o/oauth2/token", 0);
   ХТТПЗапрос.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
   
   ПараметрыПОСТ = "code=" + КодДоступа + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "client_id={}" + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "client_secret={}" + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "redirect_uri=urn:ietf:wg:oauth:2.0:oob" + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "grant_type=authorization_code";

   ХТТПЗапрос.Send(ПараметрыПОСТ);

После Send вываливается ошибка:
"A connection with the server could not be established"

всем кому интересно вэлкам, может вместе разберемся ;-)
1 Ursus maritimus
 
15.02.13
10:04
(0) Дай почту. Получишь подарок невиданной щедрости.
2 Ursus maritimus
 
15.02.13
10:05
Хотя не надо


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
   
   ЗаполнитьЗначенияСвойств(ЭтаФорма,Параметры,"ClientID,ClientSecret,APIkey,RedirectURIs,Scope");
   
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
   
   // Тип ответа сервера. Согласно документации, для установленных приложений = code
   _Параметры            = "response_type=code" + "&";
   // Параменты полученные при регистрации приложения
   _Параметры            = _Параметры + "client_id=" + ClientID + "&";
   _Параметры            = _Параметры + "redirect_uri=" + RedirectURIs + "&";
   _Параметры            = _Параметры + "access_type=offline" + "&";
   
   // Области доступа к которым будет выполняться запрос
   _Параметры            = _Параметры + "scope="+Scope;
   

   // адрес на котором пользователь выполнит авторизацию
   АдресАвторизации    = "https://accounts.google.com/o/oauth2/auth" + "?";
   
   // Формируем полный адрес авторизации вместе с параметрами
   ПолныйАдресАвторизации    = АдресАвторизации + _Параметры;
   
   // И показываем страницу пользователю
   Элементы.ПолеHTML.Документ.location.href = ПолныйАдресАвторизации;
   
   ДанныеGoogleПолучены = Ложь;

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

&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)
   
   ЗаголовокОкна    = Элементы.ПолеHTML.Документ.nameProp;
   
   // Анализируем его, ищем код доступа, выделяем из строки
   Если Лев(ЗаголовокОкна, 13) = "Success code=" Тогда
       КодДоступа    = Сред(ЗаголовокОкна, 14);
       
       Если Не ДанныеGoogleПолучены Тогда
       
           // и передаем на второй этап
           ВторойЭтапДоступа(КодДоступа);
           ДанныеGoogleПолучены = Истина;
           
       КонецЕсли;
   КонецЕсли;

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

&НаКлиенте
Процедура ВторойЭтапДоступа(КодДоступа)
   
   ХТТПЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
   // Выполняем отключение контроля сертификтов
   Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
   Скрипт.language="javascript";
   Скрипт.AddObject("ХТТПЗапрос",ХТТПЗапрос);
   Скрипт.Eval("ХТТПЗапрос.Option(4)=13056");
           
   // открываем ресурс
   ХТТПЗапрос.Open("POST", "https://accounts.google.com/o/oauth2/token", 0);
   ХТТПЗапрос.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
   
   // формируем дополнительные параметры
   ПараметрыПОСТ =                "grant_type=authorization_code" + "&";    // предопределенный в документации
   ПараметрыПОСТ = ПараметрыПОСТ + "code=" + КодДоступа + "&";                // получен на первом этапе доступа
   // получены при регистрации приложения
   ПараметрыПОСТ = ПараметрыПОСТ + "client_id="+ClientID + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "client_secret="+ClientSecret + "&";
   ПараметрыПОСТ = ПараметрыПОСТ + "redirect_uri="+RedirectURIs;
   // Отправляем для обработки сервером
   ХТТПЗапрос.Send(ПараметрыПОСТ);

   Ответ    = ЗадачиИПорученияСервер.UnJSON(ХТТПЗапрос.ResponseText());
   
   Ключи = Новый Структура;
   Ключи.Вставить("Tocken",Ответ.Получить("access_token"));
   Ключи.Вставить("Refresh",Ответ.Получить("refresh_token"));
   Ключи.Вставить("expires_in",Ответ.Получить("expires_in"));
   Закрыть(Ключи);
   
КонецПроцедуры
3 queit
 
15.02.13
10:14
Все тоже самое. И код такой же.
"redirect_uri=urn:ietf:wg:oauth:2.0:oob" такой?
4 Ursus maritimus
 
15.02.13
10:15
urn:ietf:wg:oauth:2.0:oob

У меня все работает.
5 Ursus maritimus
 
15.02.13
10:18
+ И кстати говоря именно календарь
6 Ursus maritimus
 
15.02.13
10:19
Прокси? файервол?
7 queit
 
15.02.13
10:20
Очень странно, все равно не функционирует.
Нет не прокси, ни файервола.
8 queit
 
15.02.13
10:21
ща попробую про сертификаты покурить, по результатам отпишусь.
9 Ursus maritimus
 
15.02.13
10:23
(8) Если научишься у создаваемых событий цвет менять, тоже отпишись плс.
10 queit
 
15.02.13
10:23
(9) хорошо, договорились. Спасибо за помощь ;-)
11 alexei366
 
15.02.13
10:29
Параметры пихай в адресную строку, а не в методе sent, вроде тама в sente под параметрами чот другое понимается, хотя я могу и ошибаться
12 queit
 
15.02.13
10:30
(9) слушай, у тебя нет прокси верно?
13 Ursus maritimus
 
15.02.13
10:34
(12) верно
14 queit
 
15.02.13
10:45
(13) тогда точно ушел курить тему с сертификатами :-)
15 Ursus maritimus
 
15.02.13
12:03
(14) Не знаю. Я никакие сертификаты не  устанавливал и не менял. Скрипт как раз же и отключает проверку сертификатов.
16 Torquader
 
16.02.13
01:13
Используйте ServerXMLHttpRequest - он имеет возможность управления правилами для сертификатов.
17 Лодырь
 
16.02.13
09:20
(9) Насколько я понял цвета фактически предопределенные. Потому что единственный метод у цветов: get - он как бы возвращает список цветов но не более. Редактировать их не получится.
Следовательно у событий мы можем лишь назначить цвет из предопределенной палитры. Ну или я вкорне неправ )
18 Лодырь
 
16.02.13
09:25
(17) Хотя вру, на каждый календарь мы еще имеем возможность повесить по цвету на выбор. Можно насоздавать ху.ву тучу скрытых календарей на нужную палитру и манипулировать ими.
19 Ursus maritimus
 
18.02.13
06:53
(18) Имхо можно, в api v3
Иначе зачем colorId в insert event?

Вопрос в узнать все эти colorId

https://developers.google.com/google-apps/calendar/v3/reference/events/insert
20 Лодырь
 
18.02.13
07:54
(19) Коллекция цветов у тебя есть и доступ к ней есть, но метод работы с колекцией всего 1! Ну каким образом ты создашь цвет? метода нет!!! назначить цвет из палитры можешь а создать только в пользовательском режиме при назначении цвета на календарь.
21 queit
 
18.02.13
08:05
(15) Так и не понял в чем дело. Действительно скрипт отключает проверку сертификата.
Попробовал на своём ноуте с прямым подключением все работает на ура. На персональном ПК тоже с прямым доступом ни в какую не взлетает - вываливает "A connection with the server could not be established".
На ПК с прокси тоже не работает.
Здесь возникает вопрос: как сделать работу через прокси?
Пробую следующее:
ХТТПЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.language="javascript";
Скрипт.AddObject("ХТТПЗапрос",ХТТПЗапрос);
Скрипт.Eval("ХТТПЗапрос.Option(4)=13056");
// Параметры прокси
ХТТПЗапрос.SetProxy(0,"62.76.65.107:3128");
// открываем ресурс
ХТТПЗапрос.Open("POST","https://accounts.google.com/o/oauth2/token", 0);
ХТТПЗапрос.SetCredentials("ProxyLogin","ProxyPassword", 1);    
ХТТПЗапрос.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
Резульат тот же.

Попробовал поюзать ВК "Душелов.GoogleCalendar" - отличнейшая вещь.
Получает календари, создает календари, все на ура, только вот не удаляет никак.
Кстати, раскопал в этой ВК цвет - пока опытным путем определил, что: #2952A3 - голубой, #2952A3 - красный, #875509 - фиолетовый.
22 Лодырь
 
18.02.13
08:14
(21) С компонентой Душелова - 1 проблема. Автора увы уже нет, а работает она со старыми версиями API - которые как бы умрут в обозримом будущем, насколько я понимаю.
23 queit
 
18.02.13
08:15
(22) да, это я знаю и очень сожалею :-(
24 queit
 
18.02.13
08:15
(22) просто в качестве эксперимента проверил
25 Лодырь
 
18.02.13
08:19
SetCredentials не использовал при проходе через прокси? наверняка у тебюя там атворизация стоит
26 Ursus maritimus
 
18.02.13
08:23
(20) Да мне новые цвета не нужны. Палитра вполне устроила бы. Где возможные ИД цветов бы взять?
27 queit
 
18.02.13
08:24
(25) Пробовал разные варианты:
1)
ХТТПЗапрос.SetProxy(0,"62.76.65.107:3128");
ХТТПЗапрос.Open("POST","https://accounts.google.com/o/oauth2/token", 0);
ХТТПЗапрос.SetCredentials("ProxyLogin","ProxyPassword", 1);  
2)
ХТТПЗапрос.SetProxy(0,"62.76.65.107:3128");
ХТТПЗапрос.SetCredentials("ProxyLogin","ProxyPassword", 1);
ХТТПЗапрос.Open("POST","https://accounts.google.com/o/oauth2/token", 0);
Совсем никак.
28 queit
 
18.02.13
08:24
(26) это пока для меня загадка
29 Лодырь
 
18.02.13
08:30
30 Лодырь
 
18.02.13
08:32
(27) А ты пример использования авторизации вот тут http://msdn.microsoft.com/en-us/library/windows/desktop/aa384058(v=vs.85).aspx смотрел?
31 Ursus maritimus
 
18.02.13
08:34
(29) Т.е. ты предлагаешь самому запрос писать? я думал, что ид уже известны и их можно взять.
Те цвета что в (21) не работают.
32 Лодырь
 
18.02.13
08:36
(31) Ага самому. В принципе в api версии 2 был список предопределенных цветов судя по всему о них и писал  queit
33 Ursus maritimus
 
18.02.13
08:38
(32) Вот что получается
{
"event": {
 "1": {
  "background": "#a4bdfc",
  "foreground": "#1d1d1d"
 },
 "2": {
  "background": "#7ae7bf",
  "foreground": "#1d1d1d"
 },
 "3": {
  "background": "#dbadff",
  "foreground": "#1d1d1d"
 },
 "4": {
  "background": "#ff887c",
  "foreground": "#1d1d1d"
 },
 "5": {
  "background": "#fbd75b",
  "foreground": "#1d1d1d"
 },
 "6": {
  "background": "#ffb878",
  "foreground": "#1d1d1d"
 },
 "7": {
  "background": "#46d6db",
  "foreground": "#1d1d1d"
 },
 "8": {
  "background": "#e1e1e1",
  "foreground": "#1d1d1d"
 },
 "9": {
  "background": "#5484ed",
  "foreground": "#1d1d1d"
 },
 "10": {
  "background": "#51b749",
  "foreground": "#1d1d1d"
 },
 "11": {
  "background": "#dc2127",
  "foreground": "#1d1d1d"
 }
}
}
Соответсвенно ИД 1,2,3.. 11
В приципе работает и цвет событию назначает, но только хрен поймешь какой цвет какой, пока не попробуешь.
34 Ursus maritimus
 
18.02.13
08:39
Ладно. Ща прикручу выбор цвета.
35 Лодырь
 
18.02.13
08:41
Кстати, насчет попробуешь, при создании календаря есть возможность выставить ему цвет в режиме RGB - тогда он пробует подбирать из палитры наиболее подходящий и выбирает именно его. Может чем тебе поможет.
36 Ursus maritimus
 
18.02.13
08:44
(35) Нет. Я все в primary фигачу
37 Лодырь
 
18.02.13
08:46
(36) Имею в виду что ты можешь создать календарь с RGB цветом, получить тут же новый цвет из коллекции назначить его на событие а календарь грохнуть.
38 queit
 
18.02.13
08:53
(30) Да, смотрел.
Еще вот по этому пробовал: Знатоки WinHttp.WinHttpRequest.5.1 - загляните подкат.

В качестве тестового примера:
ХТТП = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
ХТТП.SetProxy(2,"62.76.65.107:3128");
ХТТП.Open("GET", "http://microsoft.com",0);
ХТТП.SetCredentials("ProxyLogin", "ProxyPassword", 0);    
ХТТП.Send();
Пока Число(ХТТП.Status)=200 Цикл
КонецЦикла;
Сообщить(ХТТП.ResponseText());    

В цикле Status=200 - здесь совсем не пойму - получается что авторизация пройдена?!

Хотя в общем, кажется получилось. Сейчас попробую все вместе слепить.
39 queit
 
18.02.13
09:01
(38) Небеса разверзлись!!! Все получилось!!! I can't believe in it!!!

Код следующий:
ХТТПЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.language="javascript";
Скрипт.AddObject("ХТТПЗапрос",ХТТПЗапрос);
Скрипт.Eval("ХТТПЗапрос.Option(4)=13056");
// Подключение прокси
ХТТПЗапрос.SetProxy(2,"IP_proxy:Port");// Задаем параметры своего прокси сервера
// открываем ресурс
ХТТПЗапрос.Open("POST","https://accounts.google.com/o/oauth2/token", 0);
ХТТПЗапрос.SetCredentials("ProxyLogin","ProxyPassword", 0);
ХТТПЗапрос.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
Ну и дальше все стандартно.

И еще момент - в процедуре ПолучитьСписокКалендарей(Маркер) тоже нужно указать прокси, аналогично.
40 Ursus maritimus
 
18.02.13
09:02
200 значит все хорошо
41 queit
 
18.02.13
09:03
Вот еще один момент интересный есть. На первом этапе нужно нажать на кнопку "Разрешить". Как её программно нажать?
42 Ursus maritimus
 
18.02.13
09:04
(41) Никак в том и суть авторизации
43 queit
 
18.02.13
09:07
(42) очень жаль :-(
44 Лодырь
 
18.02.13
09:07
(41) Угу, никак. Зато потом ты получишь маркер и сможешь его обновлять без участия юзера. У меня на этапе создания пользователя он авторизуется первый и последний раз, далее его уже никто ниочем не спрашивает )
45 queit
 
19.02.13
06:33
Товарищи, вопрос такой - какая квота на календари и события?
46 Ursus maritimus
 
19.02.13
06:43
(45) В консоле же написано. 10 000 реквестов в день
47 queit
 
19.02.13
06:48
(46) это я видел. Реальные данные есть?
Просто мне нужно создать 120 календарей в каждом 80 событий.
Всего создается 30 календарей и ни одного события.
Пишется ошибка: Quota Exceeded
48 Ursus maritimus
 
19.02.13
06:52
Ну значит исчерпал. Распредели нагрузку по нескольким аккаунтам.
49 queit
 
19.02.13
07:10
Не совсем понимаю как я мог исчерпать лимит
Requests     % Requests    
1.11k               100.00%

Странная у них система :-)
По нескольким - это идея, спасибо ;-)
50 Лодырь
 
19.02.13
07:48
А ты случайно за 5.0 requests/second/user не вылазишь? Там тоже лимит.
51 queit
 
19.02.13
08:29
(50) я же его могу поменять.
Реально я и так и так пробовал:
1) Просто в цикле добавляю календари из списка
2) В цикле добавляю календари из списка с задержкой 5, 10, 30, 60 секунд
52 queit
 
19.02.13
10:21
В общем, не получается больше 25 календарей загрузить.
Задержка в 5, 10 и т.д. секунд не играет существенной роли.
Причем заметил еще один момент - загрузил 25 календарей (без событий), удалил все календари. В следующий раз можно загрузить где-то через 40 - 90 минут.
53 Ursus maritimus
 
19.02.13
10:25
Вообще-то странно что 25 дает. Если я правильно понял, то не должно быть больше 20 клиентов

OAuth 2.0 allows users to share specific data with you (for example, contact lists) while keeping their usernames, passwords, and other information private. A single project may contain up to 20 client IDs
54 queit
 
19.02.13
10:35
(53) т.е. получается, что всего может быть 20 календарей?
55 Ursus maritimus
 
19.02.13
10:37
(54) Не. 20 различных аккаунтов пользователей.
56 queit
 
19.02.13
10:37
(54) Если так, то где-то не сходится.
Получается у меня главный календарь + 2 подключаемых + 2 тестовых. И еще я могу загрузить, получается, 20.
Итого: 25
57 queit
 
19.02.13
10:38
(55) Что-то я не совсем понимаю.
58 Ursus maritimus
 
19.02.13
10:39
(57) У тебя 100500 календарей у одного пользователя?
59 queit
 
19.02.13
11:08
(58) Нет.
Цель у меня следующая: хочу сделать студентам расписание занятий и чтобы они подключались и смотрели занятия по своей группе. Групп где-то штук 200.
60 Лодырь
 
19.02.13
12:01
(59) Мож тебе вообще сделать импорт через ical?
61 queit
 
19.02.13
12:05
(60) что-то все там так сложно.
Но все равно, спасибо. Возможно и раскопаю ical.

Пока думаю еще повожусь с гуглом.
62 Лодырь
 
19.02.13
12:09
(61) Не, ну можно через csv вроде бы попробовать. в формате экспорта аутглюка
там проблем и ограничений по количеству быть не должно )
63 queit
 
19.02.13
12:13
(62) а ссылочкой не поделитесь?
64 Лодырь
 
19.02.13
12:19
65 queit
 
19.02.13
12:31
(64) Благодарю. Примерно понятно.
Только есть одна проблема - там совершенно не понятно как это сделать программно.
Я то планирую все это поставить в регламентное задание и пусть оно себе обновляет расписание без моего участия :-)
66 queit
 
20.02.13
13:27
Товарищи, вопрос на засыпку - по какому принципу формируется id календаря?
67 Лодырь
 
20.02.13
16:41
(66) Э... Не в курсе, да и какая разница?
68 queit
 
21.02.13
04:42
(67) а как тогда получить id календаря???
69 Лодырь
 
21.02.13
04:48
(68)вы меня пугаете...
1. Когда создаете календарь через https://developers.google.com/google-apps/calendar/v3/reference/calendars/insert
в ответе возвращается объект из которого можно выдернуть id и запомнить
2. Получить список календарей через кусок кода вида:
// Запрос без проверки сертификтов
   ХТТПЗапрос = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
   Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
   Скрипт.language="javascript";
   Скрипт.AddObject("ХТТПЗапрос",ХТТПЗапрос);
   Скрипт.Eval("ХТТПЗапрос.Option(4)=13056");
           
   ХТТПЗапрос.Open("GET","https://www.googleapis.com/calendar/v3/users/me/calendarList",0);
   ХТТПЗапрос.setRequestHeader("Authorization","Bearer " + ТокенНаДоступ);
   ХТТПЗапрос.Send();

   ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
   
   Текст = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
   Текст.ЗаписатьСтроку(ХТТПЗапрос.ResponseText());
   Текст.Закрыть();
   
   ФайлОтвета    = Новый ТекстовыйДокумент;
   ФайлОтвета.Прочитать(ИмяВременногоФайла, КодировкаТекста.UTF8);
   ТекстОтвета = ФайлОтвета.ПолучитьТекст();
   Ответ        = JSON.UnJSON(ТекстОтвета);
   
   
   
   МассивКалендарей = Ответ.Получить("items");

И дальше его спокойно обработать. Получая оттуда id тех календарей которые необходимо
70 queit
 
21.02.13
05:25
(69) Допустим я создаю календарь:
       ХТТПЗапрос.Open("POST","https://www.googleapis.com/calendar/v3/calendars/?fields=summary%2CtimeZone&key=" + API_key,0);
       
ХТТПЗапрос.setRequestHeader("Content-Type", "application/json");
ХТТПЗапрос.setRequestHeader("Authorization", "Bearer " + Маркер);
ХТТПЗапрос.setRequestHeader("X-JavaScript-User-Agent", "Google APIs Explorer");
ПараметрыПОСТ = "{
       |    ""summary"": """ + НаименованиеКалендаря + """,
       |    ""timeZone"": ""Asia/Omsk""
       |}";
ХТТПЗапрос.Send(ПараметрыПОСТ);
Результат = Результат + ХТТПЗапрос.ResponseText();

Так вот в результате следующее:

Свойство    Значение               Тип
ХТТПЗапрос    COMОбъект               COMОбъект
Option          Ошибка чтения значения        
ResponseBody    COMSafeArray               COMSafeArray
ResponseStream    COMОбъект               COMОбъект
ResponseText    "{
                  "summary": "BUP12",
                  "timeZone": "Asia/Omsk"
               }"                         Строка
Status            200                       Число
StatusText    "OK"                       Строка

Где там id я ума не приложу...

Конечно можно после добавления получать список календарей, потом его расперсивать и получать последний календарь, но все таки хочется разоюраться
71 Лодырь
 
21.02.13
05:30
(70) Гы... ты сам  говоришь его не выводить
Ты сам явно указываешь чтов  ответе тебе возвращать лишь
fields=summary%2CtimeZone
А надо тупо убрать этот кусок, тогда вернется весь объект.
то бишь запрос должен быть
POST https://www.googleapis.com/calendar/v3/calendars?key={YOUR_API_KEY}
72 queit
 
21.02.13
05:33
(71) ё-маё!!! спасибо за ликбез!!! ))) пошел дальше курить мантры )))