-
Notifications
You must be signed in to change notification settings - Fork 8
authorization
Для выполнения команд, за некоторым исключением, терминал требует авторизации. Она гарантирует что у нему подключился не кто угодно, а тот кто знает [smarthome] token
.
На попытку выполнить команду без авторизации, терминал пришлет сообщение об ошибке с кодом относящимся к команде authorization
. Например:
send -> {"method": "ping", "params": ["1551338760.8188732"], "id": "pong"}
recv <- {"error": {"code": 4210, "message": "forbidden: authorization is necessary"}, "id": "pong"}
send -> {"method": "list_models", "id": 27}
recv <- {"error": {"code": 4210, "message": "forbidden: authorization is necessary"}, "id": 27}
Выполнение данных команд не требует авторизации (пока): authorization
, hi
, voice
, play
, pause
, tts
, ask
, settings
, volume
, volume_q
, music_volume
, music_volume_q
, rec
, remote_log
.
-
{"method": "authorization", "params": ["<hash>"], "id": "any"}
.Где
<hash>
- результат хеширования[smarthome] token
sha512 в формате hexdigest.Если
[smarthome] token
не задан, то терминал не будет проверять хеш и выполнениеauthorization
будет всегда успешным. А при исходящем подключении использует хеш полученный случайным образом.
В ответ терминал пришлет результат выполнения команды или ошибку, если хеши не совпали:
-
Успех:
{"result": "authorized", "id": "any"}
. -
Неудача:
{"error": {"code": 4211, "message": "forbidden: wrong hash"}, "id": "any"}
.
Важно: При установке исходящего соединения терминал будет ожидать результат и проверять id
и result
. Он не начнет передачу команд до получения положительного результата.
Пример получения хеша на Python3:
import hashlib
token = 'secret token'
hash_ = hashlib.sha512(token.encode()).hexdigest()
Методы доступны только в JSON-RPC.
-
authorization.self: Альтернативный способ авторизации, для внутренних нужд
{"method": "authorization.self", "params": {"token": "token", "owner": "owner"}}
. -
authorization.totp: Перед хешированием токена добавляет к нему "соль" - Unix time поделенный на 2 и округленный до целого. Хеш будет постоянно меняться, но требует чтобы время на терминале и подключаемом устройстве точно совпадало. Также можно передать необязательный
timestamp
, он не участвует в хешировании но позволит узнать временную разницу:{"method":"authorization.totp","params":{"hash":"3a2af9d519e51c5bff2e283f2a3d384c6ey0721cb1d715ef356508c57bf1544c498328c59f5670e4aeb6bda135497f4e310960a77f88a046d2bb4185498d941f","timestamp":1582885520.931},"id":"8a5559310b336bad7e139550b7f648ad"}
Пример получения хеша на Dart:
String makeHash(String token, {int interval = 2}) { final timeTime = DateTime.now().toUtc().millisecondsSinceEpoch / 1000; final salt = (timeTime.roundToDouble() / interval).truncate(); return '${sha512.convert(utf8.encode(token + salt.toString()))}'; }