Процесс связывания аккаунтов и получения токенов
Связывание аккаунтов — это процесс сопряжения аккаунта Сбер ID пользователя с его аккаунтом в вашей системе. В результате умный дом Sber получает:
- access-токен, с которым может отправлять команды в ваше облако,
- refresh-токен, необходимый для обновления access-токена.
Получение access- и refresh-токенов
Получение токенов происходит по стандартному протоколу OAuth 2.0 с помощью кода авторизации (Authorization Code Grant):
Шаг 1. Выбор вендора
В приложении Салют пользователь открывает экран → Сервисы → Подключить умный дом от других производителей. Затем на вкладке Подключить выбирает нужного вендора — вас.
Шаг 2. Вызов формы авторизации вендора
Умный дом Sber обращается к вашему авторизационному серверу для получения формы авторизации:
GET https://example.com/authorize
?response_type=code
&client_id=example_id
&redirect_uri=https://example_callback_uri
&scope=example_scope
&state=example_state
Параметр | Обязательный? | Описание |
https://example.com/authorize | ✔︎ | Адрес вашего авторизационного сервера (Authorization Endpoint) — его вы указываете в Studio |
response_type | ✔︎ | Запрашиваемый умным домом тип авторизации. Используется значение code — оно указывает, что запрашивается авторизация по коду |
client_id | ✔︎ | Идентификатор клиента — приложения, запрашивающего доступ. Идентификатор вы указываете в Studio |
redirect_uri | ✔︎ | Адрес, на который авторизационный сервер будет перенаправлять пользователя после авторизации. Допустимые URI возврата:
|
scope | Поля аккаунта пользователя в вашей базе, к которым будет разрешен доступ для умного дома Sber. Эти поля вы указываете в Studio. Если в Studio scope не задан, умному дому будут доступны все данные об аккаунте | |
state | Уникальный статус авторизации, используется для предотвращения CSRF-атак. Авторизационный сервер должен возвращать этот параметр без изменения значения |
Пример запроса:
curl -i -X GET /oauth/login HTTP/1.1 \
--header Host: auth.yourserver.ru \
--header Content-Type: application/x-www-form-urlencoded \
--data-urlencode client_id=IId-DIWEnd1234h2buia \
--data-urlencode redirect_uri=https://gateway.iot.sberdevices.ru/gateway/v1/binder/backward \
--data-urlencode state=xy1234
Шаг 3. Форма авторизации вендора
В приложении Салют отображается ваша форма авторизации.
Шаг 4. Логин и пароль
Пользователь вводит в форму логин и пароль от своей учетной записи в вашей системе.
Шаг 5. Проверка логина и пароля
Ваш авторизационный сервер проверяет введенные логин и пароль пользователя.
Шаг 6. Код авторизации
Если логин и пароль верны, авторизационный сервер делает редирект на URI возврата. При этом параметр state
возвращается без изменений, а в параметре code
сервер возвращает код авторизации.
HTTP/1.1 302 Found
Location: https://example_callback_uri
?code=example_code
&state=example_state
Параметр | Обязательный? | Описание |
https://example_callback_uri | ✔︎ | Адрес перенаправления. Указывается в запросе авторизации (см. шаг 2) |
code | ✔︎ | Код авторизации |
state | ✔︎ | Уникальный статус авторизации, используется для предотвращения CSRF-атак. Если state был в запросе, он должен возвращаться без изменений |
При возникновении любых ошибок, кроме отсутствующего либо поврежденного redirect_uri
или client_id
, должен выполняться редирект на URI возврата. При этом в параметры адреса должно быть добавлено название ошибки, также должен быть возвращен параметр state
. Дополнительно в парамерах могут быть переданы детальное описание ошибки и ссылка на страницу в интернете.
Location: https://example_callback_uri
&error=example_error
&error_description=example_description
&error_uri=example_uri
&state=example_state
Параметр | Обязательный? | Описание |
https://example_callback_uri | ✔︎ | Адрес перенаправления. Указывается в запросе авторизации (см. шаг 2) |
error | ✔︎ | Название ошибки. Названия см. в спецификации OAuth 2.0 |
error_description | Детальное описание ошибки | |
error_uri | Адрес веб-страницы с дополнительным описанием ошибки | |
state | ✔︎ | Уникальный статус авторизации, используется для предотвращения CSRF-атак. Если state был в запросе, он должен возвращаться без изменений |
Если в запросе отсутствует или имеет неверный формат параметр redirect_uri
или параметр client_id
, нужно отобразить сообщение пользователю. Редирект выполнять не нужно.
Пример успешного ответа:
HTTP/1.1 302 Found
Location: https://gateway.iot.sberdevices.ru/gateway/v1/binder/backward
?code=1234567890abcdef1234567890abcdef12345678
&state=xy1234
Пример ответа с ошибкой. В примере идентификатор приложения client_id
имеет верный формат, но он не добавлен в список разрешенных на авторизационном сервере:
HTTP/1.1 302 Found
Location: https://gateway.iot.sberdevices.ru/gateway/v1/binder/backward
?error=unauthorized_client
&state=xy1234
Шаг 7. Запрос токенов
Умный дом использует полученный код, а также ваши Client ID и Secret ID и отправляет запрос на получение access-токена и refresh-токена пользователя:
POST /token HTTP/1.1
Host: https://example.com/token
Content-Type: application/x-www-form-urlencoded
client_id=example_id
&client_secret=example_secret
&grant_type=authorization_code
&code=example_code
&redirect_uri=example_callback_uri
Параметр | Обязательный? | Описание |
https://example.com/token | ✔︎ | Адрес для получения токена, который вы указали в Studio. Этот же адрес будет использоваться для обновления токенов пользователя |
client_id | ✔︎ | Идентификатор клиента — приложения, запрашивающего доступ. Идентификатор вы указываете в Studio |
client_secret | ✔︎ | Секрет клиента — ключ для проверки подлинности приложения. Его вы указываете в Studio |
grant_type | ✔︎ | Тип доступа. Принимает значение authorization_code |
code | ✔︎ | Код авторизации, полученный на шаге 6 |
redirect_uri | ✔︎ | Адрес, на который авторизационный сервер будет перенаправлять пользователя после авторизации. Идентичен |
Пример запроса:
curl -i -X POST /oauth/token HTTP/1.1 \
--header Host: auth.yourserver.ru \
--header Content-Type: application/x-www-form-urlencoded \
--data-urlencode client_id=IId-DIWEnd1234h2buia \
--data-urlencode client_secret=diwoNKJE-Owd312jdwJ \
--data-urlencode grant_type=authorization_code \
--data-urlencode code=1234567890abcdef1234567890abcdef12345678 \
--data-urlencode redirect_uri=https://gateway.iot.sberdevices.ru/gateway/v1/binder/backward
Шаг 8. Проверка Authorization Code, Client ID, Secret ID
Ваш авторизационный сервер проверяет предоставленные умным домом данные: код авторизации, идентификатор клиента и секрет клиента.
Шаг 9. Access-токен и refresh-токен пользователя
Ваш авторизационный сервер возвращает access-токен и refresh-токен пользователя. Умный дом сохраняет их и в дальнейшем использует при отправке запросов к вашему облаку.
{
"access_token": string,
"refresh_token": string,
"expires_in": integer,
"token_type": string
}
Параметр | Обязательный? | Описание |
access_token | ✔︎ | Токен доступа |
refresh_token | ✔ | Токен, использующийся для обновления access_token . Время жизни refresh_token должно быть значительно больше времени жизни access_token и составлять не менее 1 часа. Рекомендуемое значение времени жизни refresh_token — в пять раз больше времени жизни access_token |
expires_in | Время, через которое Если параметр не задан, время действия токена считается не ограниченным | |
token_type | ✔︎ | Тип токена. Используется тип Bearer : для использования токена достаточно его самого и не требуется дополнительного подтверждения прав |
Если выдать токены не удалось, ответ должен содержать название ошибки. Дополнительно могут быть переданы детальное описание ошибки и ссылка на страницу в интернете.
{
"error": string,
"error_description": string,
"error_uri": string
}
Параметр | Обязательный? | Описание |
error | ✔︎ | Название ошибки. Названия см. в спецификации OAuth 2.0 |
error_description | Детальное описание ошибки | |
error_uri | Адрес веб-страницы с дополнительным описанием ошибки |
Пример успешного ответа:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "qwerty-1234-5678",
"refresh_token": "5678-1234-qwerty",
"expires_in": 86400,
"token_type": "Bearer",
}
Пример ответа с ошибкой. В примере запрос имеет неверный формат, например из-за отсутствия какого-то из обязательных параметров:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_request"
}
Обновление access-токена пользователя
Когда указанное в параметре expires_in
время жизни access-токена пользователя приближается к истечению, умный дом Sber обращается к вашему авторизационному серверу и запрашивает обновленный токен. В ответ ваш сервер должен вернуть новую пару токенов access_token
и refresh_token
.
Обратите внимание, что даже если вы не ограничиваете время жизни токенов пользователей, на вашем сервере все равно должен быть реализован метод обновления токенов.
Формат запроса
POST /token HTTP/1.1
Host: https://example.com/token
Content-Type: application/x-www-form-urlencoded
client_id=example_id
&client_secret=example_secret
&grant_type=refresh_token
&refresh_token=example_refresh_token
Параметр | Обязательный? | Описание |
https://example.com/token | ✔︎ | Адрес для получения токена, который вы указали в Studio. Обратите внимание, что это должен быть тот же адрес, который использовался для запроса токенов пользователя |
client_id | ✔︎ | Идентификатор клиента — приложения, запрашивающего доступ. Идентификатор вы указываете в Studio |
client_secret | ✔︎ | Секрет клиента — ключ для проверки подлинности приложения. Его вы указываете в Studio |
grant_type | ✔︎ | Тип доступа. Принимает значение refresh_token |
refresh_token | ✔︎ | Текущий refresh-токен, хранящийся в умном доме |
Формат ответа
Успешный ответ:
{
"access_token": string,
"refresh_token": string,
"expires_in": integer,
"token_type": string
}
Параметр | Обязательный? | Описание |
access_token | ✔︎ | Токен доступа |
refresh_token | ✔ | Токен для обновления токена доступа |
expires_in | Время, через которое токен доступа перестанет действовать и его нужно будет обновить. Указывается в секундах. На все запросы с просроченным токеном авторизационный сервер должен отвечать ошибкой Если параметр не задан, время действия токена считается не ограниченным | |
token_type | ✔︎ | Тип токена. Используется тип Bearer : для использования токена достаточно его самого и не требуется дополнительного подтверждения прав |
Если выдать новые токены не удалось, ответ должен содержать название ошибки. Дополнительно могут быть переданы детальное описание ошибки и ссылка на страницу в интернете.
{
"error": string,
"error_description": string,
"error_uri": string
}
Параметр | Обязательный? | Описание |
error | ✔︎ | Название ошибки. Названия см. в спецификации OAuth 2.0 |
error_description | Детальное описание ошибки | |
error_uri | Адрес веб-страницы с дополнительным описанием ошибки |
Пример запроса и ответа
Умный дом отправляет запрос на обновление access-токена:
curl -i -X POST /oauth/token HTTP/1.1 \
--header Host: auth.yourserver.ru \
--header Content-Type: application/x-www-form-urlencoded \
--data-urlencode client_id=IId-DIWEnd1234h2buia \
--data-urlencode client_secret=diwoNKJE-Owd312jdwJ \
--data-urlencode grant_type=refresh_token \
--data-urlencode refresh_token=5678-1234-qwerty
Успешный ответ — ваш сервер авторизации возвращает новые access-токен и refresh-токен:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "qwerty-4321-5678",
"refresh_token": "5678-4321-qwerty",
"expires_in": 86400,
"token_type": "Bearer"
}
Ответ с ошибкой — запрос имеет неверный формат, например из-за отсутствия какого-то из обязательных параметров:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_request"
}