0
0

ブラウザでAWS IoTのMQTTブローカーを署名バージョン4認証で購読する

Last updated at Posted at 2024-09-15

概要

Firefoxなどのブラウザを用いてAWS IoTのMQTTブローカーに接続します。ブラウザからの接続の場合、WebSocketでの接続になります。AWS IoT Coreデベロッパーガイドのデバイス通信プロトコルの表によるとMQTT over WebSocketはPublisおよびSubscribeに対応しており、認証方法は署名V4(SigV4)とカスタム認証を使うことになっています。

プロトコル オペレーション 認証 ポート
MQTT over WebSocket 発行, 購読 署名V4 443
MQTT over WebSocket 発行, 購読 カスタム認証 443

独自の認証を使いたい場合はLambdaオーソライザーを使うようですが、この記事では「とにかくシンプルに使う」を目的にしているので、署名V4を使った接続方法を解説します。ここではカスタム認証の方法は扱いません。

準備

IAMユーザーの作成

接続に使用するIAMユーザーを作成します。コンソール接続は不要でプログラムからのみ使用します。例えばポリシーは以下のようにすることで、購読(subscribe)のみ可能です。発行(publish)したい場合は "iot:Publish"Action の項目に追加します。{REGION}および{AWS ACCOUNT ID}{TOPIC}は適切なものに指定してください。

インラインポリシーの例
    {
	  "Version": "2012-10-17",
	  "Statement": [
		{
          "Sid": "IoT-20240915",
          "Effect": "Allow",
          "Action": [
            "iot:Subscribe",
            "iot:Connect",
            "iot:Receive"
          ],
          "Resource": [
            "arn:aws:iot:{REGION}:{AWS ACCOUNT ID}:topicfilter/{TOPIC}",
            "arn:aws:iot:{REGION}:{AWS ACCOUNT ID}:client/*",
            "arn:aws:iot:{REGION}:{AWS ACCOUNT ID}:topic/{TOPIC}"
          ]
        }
      ]
    }

ユーザーを作成したらアクセスキーとシークレットアクセスキーをメモしておきます。

ブラウザ用AWS IoT Device SDKのビルド

Node.jsの場合はnpmでインストールすればすぐに使えるみたいですが、ブラウザ向けのjsファイルは自分で作る必要があります。browserifyでビルドします。以下はRocky Linux 9.4, node.js 20.11.1, npm 10.2.4で実行しました。

$ npm install browserify
$ git clone https://github.com/aws/aws-iot-device-sdk-js.git
$ cd aws-iot-device-sdk-js
$ npm run-script browserize

これで、browserディレクトリにaws-iot-sdk-browser-bundle.jsファイルが生成されます。

Webページの作成

ブラウザで開くWebページを作成します。ここではできるだけ単純に以下の構成にしました。wwwディレクトリはWeb公開ディレクトリです。環境に合わせて調整してください。ひょっとしたらHTTPS接続が必要かもです(すみませんHTTPSでしか試していません)。
Windows 10 22H2のFirefox 130およびEdge 128で動作確認しました。

  • www/
    • aws-iot-sdk-browser-bundle.js
    • mqttclient.html

以下がトピックを購読するための最低限のコードです。エラー処理などはしていません。

mqttclient.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>MQTT Client Test</title>
  <script src="./aws-iot-sdk-browser-bundle.js"></script>
</head>
<body>
  <p id="txtMessage">0</p>

  <script>
    const awsIot = require("aws-iot-device-sdk");   // SDKを読み込む
    const IOT_TOPIC = "MyTopic/test";               // 対象とするトピック
    const params = {
      accessKeyId:  "AKEXAMPLEACCESSKEYID",
      secretKey:    "MyExampleSecretKeyabcdef0123456789000000",
      region:       "ap-northeast-1",
      host:         "xxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com",  // iot:Data-ATSエンドポイント
      protocol:     "wss",
      clientId:     self.crypto.randomUUID(),   // 一意のクライアントID(何でもよい)
    };

    deviceIot = awsIot.device(params);  // 接続開始

    deviceIot.on("connect", () => {     // 接続されたら購読する
      console.debug("Connected!!");
      deviceIot.subscribe(IOT_TOPIC, undefined, (err, granted) => {
        console.debug("Subscribed!!");
      });
    });

    deviceIot.on("message", (topic, payload) => {  // メッセージが届いた
      const message = new TextDecoder().decode(payload);
      document.querySelector("#txtMessage").textContent = message;
    });
  </script>
</body>
</html>

mqttclient.htmlをブラウザで開くとメッセージの購読が始まります。

ポイント

  • params.clientIdrandomUUID()で求めていますが、適当な文字列が使えます。
  • awsIot.device(params)のオプションでsessionTokenも使えるので、高度な認証を行いたい場合はセッショントークンを使ってもいいかもしれません。

メッセージの発行

今回のHTMLには実装していませんが、publish()メソッドでメッセージを発行できます。
この場合、IAMユーザーにiot:Publish権限が必要となります。

Publish Example
deviceIot.publish("MyTopic/test", '{"message": "Hello, IoT World!!"}');

参考

  1. AWS IoT Coreにブラウザから様々な認証方法で接続してみる
  2. ブラウザでAWS IoT CoreにMQTTでPub/Subしたい場合にやるべきことリスト
  3. AWS IoT Coreデベロッパーガイド -- デバイス通信プロトコル
  4. AWS IoT: awsIot.device()

余談

最低限の実装というのがなかなか見つからず、署名V4でシンプルに接続したいだけなのに結構苦労しました。
TypeScriptは使わないので、AWS SDKをビルドするのが面倒…というのでできるだけシンプルな方法を探していたのですが、AWS IoT Device SDKは必要なんですね(他のやり方もあるのかもですが)。
私はM5Stackからのセンサー値の通信に使いたいなと思って試しましたが、ほぼリアルタイムな通信が簡単に実装できるので、IoTだけではなくブラウザ間通信など、アイデア次第でいろいろ遊べそうな気がします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0