MQTT 接続用トークンについて

MAGELLAN の MQTT 接続では、「OAuth 1.0 署名(Signature)認証」と「トークン認証」の 2 つの認証方式をサポートしています。

ここでは、「トークン認証」で必要となるトークンの取得方法について解説します。

トークン取得(発行)の流れ

トークン認証で必要となるトークンは、MAGELLAN が発行します。MAGELLAN が発行するトークンを取得する大まかな流れは次のようになります。

トークン取得の流れ図

  1. トークンが必要なクライアントは、Worker に対してトークン発行要求を出します。
  2. トークン発行要求を受けた Worker は、MAGELLAN にトークンの発行を依頼します。
  3. MAGELLAN は、トークンを発行します。

このため、トークン認証を利用する場合は、Worker にトークン発行機能を実装しなければなりません。

Worker のトークン発行機能実装方法

先に述べた通り、トークン認証で使用するトークンは、Worker 経由で MAGELLAN が発行します。

MAGELLAN は、Worker からの HTTP レスポンスヘッダに X-MQTT-AUTH フィールドがあると、トークンを発行します。発行したトークンは、HTTP レスポンスヘッダに Authorization フィールドを追加して、そのフィールド値にトークンを設定します。

トークン取得の詳細図

Worker のトークン発行機能の実装手順は、大まかには次のようになります。

Worker に、トークン発行用の Web API を用意します。図の例では、GET /mqtt/auth としています(メソッドは、POST でもよいです)。

トークン発行機能の処理は、HTTP レスポンスヘッダに、X-MQTT-AUTH フィールドを追加します。以下は、Rails でのコード例です(X-MQTT-AUTH フィールド値を true としていますが、どのような値でもよいです)。

response.headers['X-MQTT-AUTH'] = true

tips用アイコン

この機能は、クライアントが MQTT 接続する Worker に実装する必要があります。このため、この Worker は、HTTP 型通信と Publish/Sbuscribe 型通信の両方に対応することになります。

トピック制限機能

トークン発行時に、Publish 可能なトピックと Subscribe 可能なトピックを制限することができます。

トピックの制限は、トークン発行時の HTTP レスポンスボディに、Publish 可能なトピックの一覧と Subscribe 可能なトピックの一覧を JSON 形式のデータで設定します。

Publish 可能なトピックの一覧と Subscribe 可能なトピックの一覧は、それぞれをキーと値のペアで指定します。

キー
publish_topics Publish 可能なトピック一覧の配列
subscribe_topics Subscribe 可能なトピック一覧の配列

以下は、JSON 形式のデータ例です。

{"publish_topics":["lv1/lv2/lv3-1", "lv1/lv2/lv3-2"], "subscribe_topics":["lv1/lv2/lv3-1", "lv1/lv2/lv3-3", "lv1/lv2/lv3-4"]}

tips用アイコン

MAGELLAN は、Publish や Subscribe のトピックをチェックし、 許可されていないトピックへの Publish や Subscribe の接続を切断します。

Worker の実装例

トークン発行のための Worker 実装例を Rails を使った Worker の例で紹介します。

仕様を次のように定義します。

  • トークン発行 Web API を GET mqtt/auth で公開します。
  • トピックを制限します。
    • Publish 可能なトピック: lv1/lv2/lv3-1, lv1/lv2/lv3-2
    • Sbuscribe 可能なトピック: lv1/lv2/lv3-1, lv1/lv2/lv3-3, lv1/lv2/lv3-4

トークン発行 Web API を GET mqtt/auth で公開するため、Rails の規約に則り mqtt コントローラの auth アクションで処理するようにします。

ここでは、./bin/rails g controller コマンドを使って、トークン発行を処理するコントローラとメソッドのひな形を生成して、実装を進めます。

$ ./bin/rails g controller mqtt auth

テキストエディタで、app/controllers/mqtt_controller.rb を次の内容で編集します。

class MqttController < ApplicationController
  def auth
    # MAGELLAN へのトークン発行依頼
    response.headers['X-MQTT-AUTH'] = true

    # Publish/Sbuscribe 可能なトピックを制限
    auth = {
      publish_topics:   ["lv1/lv2/lv3-1", "lv1/lv2/lv3-2"],
      subscribe_topics: ["lv1/lv2/lv3-1", "lv1/lv2/lv3-3", "lv1/lv2/lv3-4"]
    }
    render json: auth.to_json
  end
end

先ほどのコマンドで生成された config/routes.rb のルーティング情報を確認しておきます。get 'mqtt/auth' が定義されています。これで、GET mqtt/auth のアクセスを mqtt コントローラの auth アクションで処理できます。

Rails.application.routes.draw do
  get 'mqtt/auth'

  ... 略 ...

これで実装は終わりです。あとは、この Worker を MAGELLAN にデプロイします。

デプロイに成功したら、適切なコンシューマ・キー、コンシューマ・シークレット、クライアントバージョンを指定して、https://nebula-001a-web.magellanic-clouds.net/mqtt/auth にアクセスします。レスポンスヘッダの Authorization フィールドにトークンが設定されます。