node.jsでAWS IoTにクライアント証明書でHTTPS送信する
AWS IoTにHTTPでPOSTしたいが、極力今ある環境をいじりたくないので、
既にインストールしてあったjavascriptで頑張ってみた。
HTTPでPOSTする方法の調査
基本的にMQTTでpublishするものなので、HTTPで送信する方法は情報が少なかった。
でも、必ずしもMQTTのポートが開いてることばかりじゃない!制限もあるし!
ということで、HTTPでできる方法を調べた。
分かったのは以下の通り。
①"aws iot-data publish"コマンドで、aws cli のcredentialを使って認証する。
dev.classmethod.jp
これはほぼプロトコルを意識せずに使用できる。
でも、ローカルに認証情報を生でおくので、自分のマシン以外ではなんか気がひける。
②curlでクライアント証明書を指定してPOSTする。
dev.classmethod.jp
Macだとなんか上手くいかないらしい。
しかもwindowsとかcurlがない環境だと面倒臭い。
今回は①も②もなんか採択するには微妙なので、第3の方法として、javascriptでなんとかPOSTできないかと思って足掻いてみた。
クライアント側の準備
①node.jsをインストール
②プロジェクトの作成
③npm install request
AWS IoT側の準備(モノやポリシーの設定は省略)
①POSTに必要な情報をAWS IoTから取得しておく。
・エンドポイント:IoT Core > 設定 > カスタムエンドポイント > エンドポイント
・認証情報
モノにアタッチするポリシーを作成する際に、ダウンロードして有効化しておく。
-プライベートキー
-モノの証明書
-ルートCA(表示されたURLをたどって、ダウンロードする。)
②テストからテスト用のトピックをサブスクライブしておく。
nodeの実装
requestでPOSTする際に、メッセージをBodyに持たせる形で送信する。
AWS IoT側ではstringで取得される。
埋め込む変数は以下の通り。
$ENDPOINT:エンドポイント
$TOPIC:テストでサブスクライブしているトピック
$PRIVATE_KEY:プライベートキー
$CERTIFICATE_OF_THINGS:モノの証明書
$ROOT_CA:ルートCA
$MESSAGE:送信するメッセージ
var request = require('request'); var fs = require('fs'); var options = { url: 'https://$ENDPOINT:8443/topics/$TOPIC', method: 'POST', key: fs.readFileSync($PRIVATE_KEY), cert: fs.readFileSync($CERTIFICATE_OF_THINGS), ca: fs.readFileSync($ROOT_CA), requestCert: true, body: $MESSAGE, rejectUnauthorized: true } request(options, function(error, response, body){ console.log(error); console.log(response); console.log(body); });