Аутентификация и авторизация

По способу аутентификации пользователя API Мегаплана похоже на REST-интерфейс Amazon. Тем не менее есть небольшие отличия, которые далее будут описаны.

Прежде всего, для аутентификации потребуется пара значений AccessId и SecretKey, которые уникальны для каждого пользователя. Получить эту пару можно с помощью запроса авторизации. Сам запрос авторизации делается напрямую, без каких-либо специальных HTTP-заголовков (в отличии от остальных запросов к API). Важно делать запрос авторизации через HTTPS-протокол, т.к. в параметрах передается функция MD5 от пароля пользователя, которая при простом и небезопасном пароле может быть «дешифрована» с помощью баз данных MD5-паролей.

Для всех остальных запросов к API требуется передавать набор HTTP-заголовков:

  • Date: <дата запроса в формате RFC-2822>

  • Accept: application/json

  • X-Authorization: <AccessId>:<Signature>

X-Authorization - специальный заголовок аутентификации, который состоит из значения AccessId и сигнатуры, формируемой специальным образом.

Если запрос отправляется методом POST, то дополнительно в заголовки включается заголовок Content-MD5.

Некоторые библиотеки не поддерживают установку значения заголовка Date при формировании HTTP-запросов, в таких случаях следует использовать заголовок X-Sdf-Date. Значение из X-Sdf-Date является более приоритетным, чем значение из Date. Т.е. если отправлены сразу оба заголовка, то в процессе аутентификации будет использован X-Sdf-Date.

Запрос на получение параметров доступа

URI: /BumsCommonApiV01/User/authorize.api|xml

Важно! Запрос должен делаться с использованием безопасного протокола HTTPS, т.к. в параметрах передается MD5 пароля пользователя, которое при простом и небезопасном пароле может быть «дешифровано» с помощью баз данных MD5-паролей.

Входные параметры

Параметр

Тип

Описание

Login

string

Логин пользователя

Password

string

MD5 пароля пользователя

OneTimeKey

string

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

Выходные данные

Параметр

Тип

Описание

AccessId

string

ID доступа для формирования сигнатуры запросов

SecretKey

string

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

UserId

integer

Идентификатор залогиневшегося пользователя

EmployeeId

integer

Идентификатор залогиневшегося сотрудника

Примеры ответов в JSON-формате

В случае отсутствия обязательного параметра

{
  "status":
  {
    "code":"error",
    "message":"Required parameter is not specified"
  }
}

В случае успешной авторизации

{
  "status":
  {
    "code":"ok",
    "message":null
  },
  "params":
  {
    "Login":"someuser",
    "Password":"202cb962ac59075b964b07152d234b70"},
  "data":
  {
    "AccessId":"5f615c654865eAddF0c2",
    "SecretKey":"2Dd0E3ff3d4a7e3695d3CeD3ec9Ff8D39D67365c",
    "UserId":12324,
    "EmployeeId":1000001
  }
}

Примеры ответов в XML-формате

В случае отсутствия обязательного параметра

<?xml version="1.0" encoding="utf-8"?>
<response>
  <status>
    <code>error</code>
    <message>Required parameter is not specified</message>
  </status>
</response>

В случае успешной авторизации

<?xml version="1.0" encoding="utf-8"?>
<response>
  <status>
    <code>ok</code>
    <message></message>
  </status>
  <params>
    <login>someuser</login>
    <password>202cb962ac59075b964b07152d234b70</password>
  </params>
  <data>
    <access_id>5f615c654865eAddF0c2</access_id>
    <secret_key>2Dd0E3ff3d4a7e3695d3CeD3ec9Ff8D39D67365c</secret_key>
    <user_id>234234234</user_id>
    <employee_id>1000001</employee_id>
  </data>
</response>

Параметры доступа для приложений

Если API используется из приложения, то запрос параметров доступа не требуется. В качестве AccessId используется UUID приложения, а в качестве SecretKey - API-токен. Узнать их значения можно на странице редактирования приложения. В этом случае все API-запросы будут проходить от лица, создавшего приложение.

Алгоритм формирования сигнатуры

1. Подготовка строки

Подготовить строку, содержащую параметры запроса, разделенные символом переноса строки (кроме Host и URI):

  • Method - метод запроса, например POST или GET

  • Content-MD5 - MD5 тела запроса (В данный момент параметр не актуален)

  • Content-Type - тип данных запроса, например application/x-www-form-urlencoded

  • Date - дата запроса в формате RFC-2822, например Wed, 25 May 2011 16:50:58 +0400 (должна с точностью до секунды совпадать с Date или X-Sdf-Date в заголовке)

  • Host - Имя хоста аккаунта, например demo.megaplan.ru

  • URI - адрес запроса, например /BumsTaskApiV01/Task/list.api|xml для получения списка задач

Пример формирования строки на PHP:

<?php
$stringToSign = $Method . "\n" .
$ContentMD5 . "\n" .
$ContentType . "\n" .
$Date . "\n" .
$Host . $Uri;

Т.к. параметр заголовка Content-MD5 более не актуален, то переменная $ContentMD5 в примере должна оставаться пустой.

Пример формирования строки на PHP для GET-запроса получения списка задач:

GET\n
\n
\n
Wed, 25 May 2011 16:50:58 +0400\n
accountname.megaplan.ru``/BumsTaskApiV01/Task/list.api|xml``

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

2. Кодирование строки

Закодировать полученную в п.1 строку с использованием алгоритма HMAC-SHA1 с ключом SecretKey, полученным ранее при авторизации пользователя.

$encrypted = hash_hmac('sha1', $stringToSign, $secretKey, false);

3. Закодировать полученное в п.2 значение алгоритмом MIME base64

$signature = base64_encode($encrypted);

Пример сформированных сигнатур и запросов

Авторизация:

Host: example.megatest.local
Login: megauser
Password: 12345
Password MD5: 827ccb0eea8a706c4c34a16891f84e7b

Полученные ключи для дальнейшей подписи:

AccessId = "8123c06c365225e110dc"
SecretKey = "fd57A98113F7Eb562e34F5Fa1c1fDc362dbdE103"

GET запрос:

Sign = "GET\n\n\nTue, 09 Dec 2014 10:29:11 +0300\nexample.megatest.local``/BumsCrmApiV01/Contractor/list.api|xml``?FilterId=all&Limit=1&Phone=1"
SecretKey = "fd57A98113F7Eb562e34F5Fa1c1fDc362dbdE103"
Hash = "NzQzMGZkMGI1OWYyZTQyNGMzMWVhZTMxMDBiZTk2ODRlMGM3ZTY3NQ=="
Header =
"Date: Tue, 09 Dec 2014 10:29:11 +0300
X-Authorization: 8123c06c365225e110dc:NzQzMGZkMGI1OWYyZTQyNGMzMWVhZTMxMDBiZTk2ODRlMGM3ZTY3NQ==
Accept: application/json"

POST запрос:

Sign = "POST\n\napplication/x-www-form-urlencoded\nTue, 09 Dec 2014 11:06:23 +0300\nexample.megatest.local``/BumsCrmApiV01/Contractor/list.api|xml``"
SecretKey = "fd57A98113F7Eb562e34F5Fa1c1fDc362dbdE103"
Hash = "MjdmZTM5ZTJjM2RhMDliMDdiODk2OWQ0YTYxNDQ1NzllMzU4MjIxYg=="
Header =
"Date: Tue, 09 Dec 2014 11:06:23 +0300
X-Authorization: 8123c06c365225e110dc:MjdmZTM5ZTJjM2RhMDliMDdiODk2OWQ0YTYxNDQ1NzllMzU4MjIxYg==
Accept: application/json
Content-Type: application/x-www-form-urlencoded"

Генерация одноразового ключа для авторизации

URI: /BumsCommonApiV01/User/createOneTimeKeyAuth.api|xml

Важно! Запрос должен делаться с использованием безопасного протокола HTTPS, т.к. в параметрах передается MD5 пароля пользователя, которое при простом и небезопасном пароле может быть «дешифровано» с помощью баз данных MD5-паролей.

Входные параметры

Параметр

Тип

Описание

Login

string

Логин пользователя

Password

string

MD5 пароля пользователя

Выходные данные

Параметр

Тип

Описание

OneTimeKey

string

Ключ одноразовой авторизации

Идентификационная информация

URI: /BumsCommonApiV01/UserInfo/id.api|xml

Возвращает идентификационную информацию текущего залогиненного пользователя.

Входные параметры

Выходные данные

Параметр

Тип

Описание

UserId

integer

Идентификатор пользователя

EmployeeId

integer

Идентификатор сотрудника (если вход выполнен под сотрудником)

ContractorId

integer

Идентификатор клиента (если вход выполнен под клиентом)