Первый опыт работы с Google API (на примере ContactsAPI) и OAuth2.0 на чистом HTTP

  • Tutorial
В ходе написания проекта мне понадобилось добавлять записи в книгу контактов Google. Вроде бы все просто, есть API, бери и пользуйся, но взять и использовать его сразу не получилось. Много документации, перекрестных ссылок (само собой не на русском языке). Мне понадобилось много времени чтобы во всем этом разобраться. Кроме того, мне нужны были пример использования в чистом протоколе HTTP без кода на каком-либо другом языке. После того, как все получилось я решил написать сюда чтобы сэкономить кому-нибудь много времени, разложив все шаги по полочкам. Для многих ничего нового здесь не будет, тем более что эта статья — большей частью перевод и упрощение гугловской документации.

Первая часть. Создание приложения и настройка


Итак, конкретно для моих целей нужно было использовать Contacts API. Заходим в свой google аккаунт в котором хотим включить API. Переходим по ссылке
console.developers.google.com/iam-admin/projects и нажимаем «Создать проект»:

image

Дальше делаем все то, что предлагает Google, никуда не сворачивая. Задаем имя проекту и т.д.

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

Также необходимо включить API. Для этого переходим на console.developers.google.com/apis/, выбираем из списка необходимый API и в открывшейся вкладке нажимаем «Включить API». Все, на этом первый шаг закончен.

Вторая часть. Получение токенов


Для обращения к API необходимо получить токены доступа по стандарту OAuth 2.0. Это, пожалуй, было для меня сложнее всего. Разобраться как, куда и какие запросы посылать, в каком порядке — не так уж и просто.

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

1. Получить code
На этом шаге производится запрос пользователю на получение доступа. Пример запроса (символом * просто заменены некоторые данные моего приложения):

https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.google.com/m8/feeds&access_type=offline&include_granted_scopes=true&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=921647******-l5jcha3bt7r6q******bhtsgk*****um6.apps.googleusercontent.com

Подробнее о некоторых параметрах:

scope — сервис, к которому мы получаем доступ. Для контактов это www.google.com/m8/feeds. Список адресов разных сервисов находится по ссылке developers.google.com/identity/protocols/googlescopes;

access_type — тип доступа. Если вам нужно будет обновлять токены без участия пользователя, обязательно используйте значение offline. Также возможно значение online, но при его выборе необходимо будет каждый раз запрашивать разрешение у пользователя в браузере;

redirect_uri и client_id — данные, которые указаны в файле проекта, который был скачан на первом этапе;

При выполнении этого GET запроса появится страница разрешений:

image

Если нажать «Разрешить», вы получите code, выглядит примерно так (* — замена моих данных):
4/iLcXnhpU8NvMHT5aTy8JjXhcROERzkvKq********

2. Получить токены
Для получения токенов авторизованного доступа необходимо послать POST запрос на адрес
www.googleapis.com/oauth2/v4/token (Обязательно, content-type запроса должен быть application/x-www-form-urlencoded).

В теле запроса должны быть следующие параметры:

code=4/iLcXnhpU8NvMHT5aTy8JjXhcROERzkvKq********&client_id=921647******-l5jcha3bt7r6q******bhtsgk*****um6.apps.googleusercontent.com&client_secret=hi1W9GAKGer************&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code

Где
code — данные, полученные на предыдущем шаге;
grant_type — обязательный параметр, который должен быть равен «authorization_code» (не какой-либо код авторизации, а именно так, буквами — authorization_code).

Ответ вы получите в формате JSON, в котором будут указаны токен досупа и токен обновления токена доступа.

Пример ответа:

image

3. Обновить токен доступа
Токен доступа (access_token) действует ограниченное время, указанное в параметре expires_in. После истечения срока действия токен доступа можно обновить по токену обновления (refresh_token).

Для этого необходимо сделать POST запрос на www.googleapis.com/oauth2/v4/token (Обязательно, content-type запроса должен быть application/x-www-form-urlencoded).
Тело запроса:

client_id=921647******-l5jcha3bt7r6q******bhtsgk*****um6.apps.googleusercontent.com&client_secret=hi1W9GAKGer************&refresh_token=1/rCIfgox0M7ul5uKHasqk****************&grant_type=refresh_token

В ответе, опять же в формате JSON вы получите новый токен доступа.

Все, полученные данные можно использовать для выполнения ваших задач. Все, что было написано выше — авторизация приложения по протоколу OAuth 2.0. Далее, для выполнения авторизованных запросов необходимо передать в параметрах токен доступа (http://google..................com/?access_token=ya.23*****************).

Работа с Contacts API


Для моей задачи мне нужно было всего три действия: Добавить контакт, получить список контактов и удалить контакт.

1. Получение списка контактов
Для получения списка контактов достаточно отправить GET запрос с параметрами. Пример запроса:

www.google.com/m8/feeds/contacts/gmm********@gmail.com/full?access_token=ya29.GlwbBFzl0uXJG6yt_Wdgr6vI4KJ88Djw85H******************************************************.
В ответе вы можете распарсить данные и получить число контактов, их описание и их ID.
gmm**********@gmail.com — адрес моей учетной записи.

2. Добавление контактов
Для добавления контактов в адресную книгу надо отправить POST запрос с токеном доступа в параметрах. (Обязательно, content-type запроса должен быть application/atom+xml). Пример запроса:

www.google.com/m8/feeds/contacts/gmm*********@gmail.com/full?access_token=ya29.GlwYBLz6AgOE9Xs****************************************************************************.
Тело запроса (взято из google документации):

<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:gd="http://schemas.google.com/g/2005">
  <atom:category scheme="http://schemas.google.com/g/2005#kind"
    term="http://schemas.google.com/contact/2008#contact"/>
  <gd:name>
     <gd:givenName>Elizabeth</gd:givenName>
     <gd:familyName>Bennet</gd:familyName>
     <gd:fullName>Elizabeth Bennet</gd:fullName>
  </gd:name>
  <atom:content type="text">Notes</atom:content>
  <gd:email rel="http://schemas.google.com/g/2005#work"
    primary="true"
    address="liz@gmail.com" displayName="E. Bennet"/>
  <gd:email rel="http://schemas.google.com/g/2005#home"
    address="liz@example.org"/>
  <gd:phoneNumber rel="http://schemas.google.com/g/2005#work"
    primary="true">
    (206)555-1212
  </gd:phoneNumber>
  <gd:phoneNumber rel="http://schemas.google.com/g/2005#home">
    (206)555-1213
  </gd:phoneNumber>
  <gd:im address="liz@gmail.com"
    protocol="http://schemas.google.com/g/2005#GOOGLE_TALK"
    primary="true"
    rel="http://schemas.google.com/g/2005#home"/>
  <gd:structuredPostalAddress
      rel="http://schemas.google.com/g/2005#work"
      primary="true">
    <gd:city>Mountain View</gd:city>
    <gd:street>1600 Amphitheatre Pkwy</gd:street>
    <gd:region>CA</gd:region>
    <gd:postcode>94043</gd:postcode>
    <gd:country>United States</gd:country>
    <gd:formattedAddress>
      1600 Amphitheatre Pkwy Mountain View
    </gd:formattedAddress>
  </gd:structuredPostalAddress>
</atom:entry>

Всю структуру оставляем такую же, меняем только персональные данные (имя, номер и т.д.).

3. Удаление контакта
Для удаления контакта надо узнать его ID (его можно получить или в ответе при добавлении контакта или при получении всего списка контактов) и отправить DELETE запрос.

ВАЖНО! В header запроса обязательно надо добавить параметр If-Match и задать его значение как *. Без этого удалить контакт не получится.

Пример запроса:

www.google.com/m8/feeds/contacts/gmm***@gmail.com/base/5a5415d78e677387?access_token=ya29.GlwYBLz6AgOE9Xsnt8Z1raYaa3fB*********************
5a5415d78e677387 — ID контакта.

Оригиналы документации google:

Using OAuth 2.0 for Web Server Applications.
Google Contacts API.

На этом все, я буду очень рад, если кому-нибудь пригодится статья. Лично мне, человеку, который впервые столкнулся с google API, было довольно трудно со всем этим разобраться.

Комментарии 3

    0
    у гугла еще есть очень удобный плэйграунд:
    https://developers.google.com/apis-explorer/?hl=en_US#p/
      0
      После того, как создание проекта будет завершено, вы сможете скачать файл со всеми данными проекта (ID, секрет и т.п.).

      проект создал, но что-то не могу понять, где это скачивается
      и вообще как-то всё поменялось, клауд теперь называется вместо гугл-апи…
        0
        Ваш пример не учитывает добавление контакта в группу.
        Я убил много времени чтобы понять как это делается.
        В офф.доках нет про это никаких примеров вообще! Даже в англоязычном инете толком не найти, будто специально скрывают! Xml фид надо изменить!
        Также, написал для себя свой класс с методами для google contacts, sheets, youtube сервисов, автоматизировав получение ключей.
        Кстати, не вздумайте распарсивать данные средствами xml встроенные в php или грубо через json_encode или (array) в фиде не будет номеров и данных от тегов gd:! Лучше просто сразу запросить json данные.
        Если нужно кому по деловой задаче, обращайтесь, помогу, за скромное вознаграждение))
        Кстати, с контактами можно работать через макросы google apps, это даже проще.
        Вообще, считаю гугловские апи это редкостное говнище каких свет не видывал, видимо их точно пишут те кто *угловостью ударился!

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое