Skip to content

authorization

Aculeasis edited this page Feb 28, 2020 · 9 revisions

Для выполнения команд, за некоторым исключением, терминал требует авторизации. Она гарантирует что у нему подключился не кто угодно, а тот кто знает [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()))}';
    }