уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Неделя прошла, можно сказать, не зря. Одним из главных событий неделю для меня стало то, что все-таки заставил себя залезть в мануалы по Delphi, немного подготовиться и пройти тест в Delphi Certification Program. Экзамен сдал, сертификат получил — осталось распечатать в цвете и повесить на стенку =).

В остальном, что касается Delphi — идей по чести Delphi XE2 громадьё, а времени сейчас практически нет. Но, тем не менее, сегодня у меня вынужденный отдых от работы — заболел. И пока болею решил потратить время с пользой — решить некоторый проблемы по части работы с Google OAuth 2.0., которые частично были указаны в комментариях к одному из постов, посвященных этой теме.

Итак, вначале разберемся с тем, что случилось с авторизацией в OAuth. Для того, чтобы разобраться в проблеме я воспользовался демкой к посту «Google API в Delphi. Обновление модуля для OAuth.«. Действительно, токен был успешно получен, но на любой запрос к API возвращалась ошибка с сообщением о том, что авторизация провалена. Проблема крылась, как оказалось, в оформлении запроса, а именно — в заголовках запроса. Все дело в том, что когда я впервые писал про Google OAuth — это было в статье «Google API в Delphi. OAuth для Delphi-приложений.«, то для правильной авторизации в сервисе использовался стандартный заголовок авторизации:

Authorization: OAuth ВАШ_ТОКЕН

и это нормально, правильно и замечательно. Но в Google в какой-то момент решили сделать ещё нормальнее и правильнее (говорю без иронии — см. протокол OAuth 2.0.) и теперь заголовок авторизации для настольных приложений стал выглядеть так:

Соответственно, уже только одно это изменение стало причиной того, что полученный токен не работал. НО это оказалось не единственной проблемой. Теперь для получения доступа к API Google по OAuth надо указывать не один, а два заголовка:

Authorization: Bearer YOUR_ACCESS_TOKEN
Host: accounts.google.com

Вот чего я так и не смог понять, так это зачем указывать вручную заголовок Host, который заполняется автоматом перед отправкой запроса на основании URL? То ли это опечатка в документации Google, то ли злая шутка разработчиков — не знаю, но без этого заголовка Host запрос к API проваливается. В общем я решил воспользоваться вторым вариантом авторизации и использовать не заголовки для указания токена, а параметры запроса.
В итоге модуль GoogleOAuth.pas претерпел некоторые изменения, а точнее метод PrepareParams. Теперь он стал таким:

function TOAuth.PrepareParams(Params: TStrings): string;
var
  S: string;
begin
  if Assigned(Params) then
    begin
      {вставляем параметр с токеном авторизации}
      Params.Add('access_token='+FAccess_token);
      for S in Params do
        Result := Result + TIdURI.ParamsEncode(S) + '&';
      Delete(Result, Length(Result), 1);
      Result := '?' + Result;
      Exit;
    end;
  Result := '';
end;

После этого запросы к API Google Tasks стали проходить без проблем.
Теперь, что касается работы с API Google Tasks. Ещё до того как Google не запостил в своем блоге информацию про «убийство 18-ти API» я задумывал разработать небольшой модуль для работы с API Задач. Работа, можно сказать, повисла практически в самом начале, но тем не менее, кое-какие моменты для работы с API были реализованы. Тот самый модуль (кому интересно) можно скачать по ссылке в конце поста. В модуле реализован следующий класс:

type
  TGTaskAPI = class(TComponent)
  private
    FOAuthClient: TOAuth;
    function GetVersion: string;
    procedure SetOAuthClient(const Value: TOAuth);
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    function ListsList(maxResults: string = ''; pageToken: string = ''): string;
    function ListsGet(const ListID: string): string;
    function ListsInsert(JSONStream: TStringStream):string;
    function TasksList(const ListID: string):string;overload;
    function TasksList(const ListID: string; Params:TStrings):string;overload;
    function TasksGet(const ListID: string; TaskID:string):string;overload;
    function TasksGet(const TaskID: string):string;overload;
    function TasksInsert(const ListID, Parent, Previous: string; JSONStream: TStringStream):string; overload;
    function TasksInsert(const ListID: string; JSONStream: TStringStream):string; overload;
    function TasksInsert(const JSONStream: TStringStream):string; overload;
    function TasksMove(const ListID, TaskID, parentTaskID, previousTaskID:string):string;overload;
    function TasksMove(const TaskID, parentTaskID, previousTaskID:string):string;overload;
    function TasksUpdate(const ListID,TaskID:string; JSONStream: TStringStream):string;overload;
    function TasksUpdate(const TaskID:string; JSONStream: TStringStream):string;overload;
    function TasksDelete(const ListID,TaskID:string):boolean;overload;
    function TasksDelete(const TaskID:string):boolean;overload;
    property Version: string read GetVersion;
    published
    property OAuthClient: TOAuth read FOAuthClient write SetOAuthClient;
  end;

То есть класс TGTaskAPI активно использует тот самый компонент для работы с OAuth 2.0. с проблем которого я и начал эту статью. Как вы можете видеть по описанию класса, методы TGTaskAPI возвращают только строки или boolean-значения. Если метод возвращает строку, то эта строка ни что иное как JSON-объект и для его разбора Вы можете воспользоваться любой удобной для Вас библиотекой, например SuperObject или родными модулями Delphi для работы с JSON — DBXJSON (для Delphi XE),  Data.DBXJSON (для Delphi XE2) или System.JSON для более поздних версий.

Что касается примера работы, то, думаю, что по мере наличия времени набросаю пример того, как можно работать с API Google Tasks без использования сторонних библиотек — только Indy и DBXJSON System.JSON. Думаю, что такой пример будет не лишним.

Скачать исходник: Исходники —> API онлайн-сервисов —> Google API

Книжная полка

Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
купить книгу delphi на ЛитРес
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
купить книгу delphi на ЛитРес
0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
7 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Николай
Николай
21/09/2011 21:05

Спасибо большое.
Но не могли бы вы сказать, реально ли сделать работу с Google Tasks через ClientLogin с передачей Auth? Ибо если регать через OAuth, то количество запросов действительно сокращается до 5000 на всех, кто юзает программу, а вот если каждый будет входить через свой gmail, то тут уже количество увеличивается до 5000 на каждого. Поэтому и интересует вопрос по входу через ClientLigin.
 
Заранее спасибо большое и огромное вам! Действительно порекомендовал данный блог многим своим знакомым Delphiстам, и людям продвигающим сайты.  Все как и я очень довольны подобной находкой!

trackback

[…] деле экзамен я уже давно сдал и получил сертификат, о чем упоминал в одной из статей в блоге, но это письмо заставило […]

Sergej Kuwakin
01/06/2017 15:15

Доброго времени суток. Спасибо за хороший материал! Но одно место никак не могу понять… Создал я проект, получил все необходимые данные. все хорошо, но… Ведь я же буду ограничен только своим аккаунтом. А хотелка звучит так, как получить содержимое произвольного аккаунтв ютуб, зная его логин и пароль. Подскажите плиз направление куда копать… Заранее спасибо!

Sergej Kuwakin
02/06/2017 21:35
Ответить на  Vlad

Спасибо за ответ! Буду думать… «можно просто получить множество OAuth-токенов к любому количеству аккуантов и их использовать» вот тут-то и зарыта собака… мне заране в принципе не ищвестны какие аккаунты потребуются…