MQTT 接続用トークンについて
MAGELLAN の MQTT 接続では、「OAuth 1.0 署名(Signature)認証」と「トークン認証」の 2 つの認証方式をサポートしています。
ここでは、「トークン認証」で必要となるトークンの取得方法について解説します。
トークン取得(発行)の流れ
トークン認証で必要となるトークンは、MAGELLAN が発行します。MAGELLAN が発行するトークンを取得する大まかな流れは次のようになります。
- トークンが必要なクライアントは、Worker に対してトークン発行要求を出します。
- トークン発行要求を受けた Worker は、MAGELLAN にトークンの発行を依頼します。
- 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
この機能は、クライアントが 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"]}
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
フィールドにトークンが設定されます。