API Keyを使えるセキュアなMilkcocoaノード

[Milkcocoa](https://mlkcca.com/)はIoTデバイス・スマートフォン・PC間で簡単にリアルタイムなデータのやり取りが出来るプラットフォームです。

MQTTにも対応しているので @ohisama@github さんが[node-red用websocketブリッヂ その2](http://qiita.com/ohisama@github/items/fdfdade6d5f46edb46e1) で書いていただいたようにMQTTノードでも利用できます。

ただ、特定のデバイスやクライアントからしかメッセージングできないセキュアな設定をするためには [Milkcocoaの認証について（2015年11月バージョン）](http://qiita.com/syuhei/items/20ac99b93ff3d3ac9ec4) に対応しなければいけません。

この中でNode-REDとして対応しやすかったAPI Key認証に対応したノードを [node-red-contrib-milkcocoa](https://www.npmjs.com/package/node-red-contrib-milkcocoa)  として公開しました。

## Milkcocoa Outputノード

Milkcocoaにデータを送信できます。

### アカウントの設定

まずは、ノードを配置してMilkcocoaノードをダブルクリックして設定ダイアログを開き、以下の画像の赤丸で囲ったアイコンをクリックしてアカウントを登録します。

<img width="902" alt="スクリーンショット 2015-12-21 15.40.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/28d44bf9-401e-72f9-4153-a6db92abfb78.png">

以下のようにMilkcocoaのApp ID, API Key, API Secretを登録します。API Key, API Secretは任意です。入力しなければ認証なしでのアクセスとなります。

<img width="502" alt="スクリーンショット 2015-12-21 17.30.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/ab3060e8-2657-e28e-c8e5-18c46b277716.png">

MilkcocoaのApp IDは以下にあります。

<img width="1173" alt="スクリーンショット 2015-12-21 15.53.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/b6f05cab-ec97-0ab1-c226-0c34bd7a9044.png">

MIlkcocoaのAPI Key, API Secretは以下で設定します。

<img width="1174" alt="スクリーンショット 2015-12-21 15.57.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/20d1d3ba-1a7b-6b7f-aef3-3baab05c82fa.png">

### データストアの指定

対象とするMilkcocoaのデータストアを指定します。

<img width="900" alt="スクリーンショット 2015-12-21 16.03.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/524fc52d-df35-52c7-7fba-6f0256d74148.png">

Milkcocoaの既存データストアは以下です。ここにないデータストア名を指定した場合は最初のデータを投入したタイミングでデータストアが作成されます。

<img width="1173" alt="スクリーンショット 2015-12-21 16.12.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/7941dadb-189e-f824-90b6-7842c195cbe3.png">

最後に指定したデータストアのセキュリティルールをMilkcocoaで設定します。messageデータストアのすべてのオペレーションにAPI Key認証を適用するには以下のような設定になります。

<img width="1173" alt="スクリーンショット 2015-12-21 17.12.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/8f554fc1-e154-3e29-a7a4-58abb78cc74e.png">

```
message {
  permit: all;
  rule : account.key == 'API_Key';
}
```

### オペレーションを選択

Milkcocoa Outputノードが受け取るデータをどうするか選択できます。

<img width="902" alt="スクリーンショット 2015-12-21 16.27.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/37d4c606-e37c-b9fe-46c5-d1e9f75b674a.png">

各オペレーションの意味は以下です。

* push: データストアに新しくデータを追加します。
* send: データストアにデータを残さず、現在接続されているユーザーにデータを送信* することができます。
* set: データストアの要素を変更します。
* remove: データストアからデータを削除します。

### データ投入

とりあえずデータを投入するには以下のようにInjectノードにJSON文字列を指定します。

<img width="905" alt="スクリーンショット 2015-12-21 16.38.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/63fe2437-9ecd-47cc-75b6-ea8c1d584f4b.png">

InjectノードのボタンをクリックしてDebugノードが以下のようなデバッグを出力すれば問題なくデータが投入されています。Milkcocoaの管理画面でも確認してみましょう。

<img width="898" alt="スクリーンショット 2015-12-21 16.50.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/1e8fa616-4ae9-e666-ebf9-c1e603c6d4da.png">

## Milkcocoa Inputノード

Milkcocoaのデータストアを監視します。オペレーションの意味は以下です。

* push: データストアのpushイベントを監視します。
* send: データストアのsendイベントを監視します。
* set: データストアのsetイベントを監視します。
* remove: データストアのremoveイベントを監視します。

以下のようにpushを監視する設定してDebugに表示されればOKです。

<img width="900" alt="スクリーンショット 2015-12-21 17.03.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/21109/4dc5cb1d-3ef9-cf24-5abc-a8c3cd16182d.png">

## まとめ

上記で作成したMilkcocoaノードを使ったフローは以下です。

```json
[{
	"id": "cdd872f2.32279",
	"type": "milkcocoa",
	"appId": ""
}, {
	"id": "a1abe025.5e542",
	"type": "inject",
	"name": "",
	"topic": "",
	"payload": "{\"test\":123}",
	"payloadType": "string",
	"repeat": "",
	"crontab": "",
	"once": false,
	"x": 123,
	"y": 57,
	"z": "d152eab6.2ead18",
	"wires": [
		["73104393.8cefbc"]
	]
}, {
	"id": "73104393.8cefbc",
	"type": "milkcocoa out",
	"milkcocoa": "cdd872f2.32279",
	"dataStore": "message",
	"operation": "push",
	"targetId": "",
	"name": "",
	"x": 306,
	"y": 57,
	"z": "d152eab6.2ead18",
	"wires": [
		["fd5ae5bc.02a518"]
	]
}, {
	"id": "fd5ae5bc.02a518",
	"type": "debug",
	"name": "",
	"active": true,
	"console": "false",
	"complete": "false",
	"x": 500,
	"y": 59,
	"z": "d152eab6.2ead18",
	"wires": []
}, {
	"id": "b9dedb60.462128",
	"type": "milkcocoa in",
	"milkcocoa": "cdd872f2.32279",
	"dataStore": "message",
	"operation": "push",
	"name": "",
	"x": 202,
	"y": 130,
	"z": "d152eab6.2ead18",
	"wires": [
		["fd5ae5bc.02a518"]
	]
}]
```

## おまけ:セキュリティルール

Milkcocoaでは前述したセキュリティルールでデータアクセス権限を柔軟に操作できます。

たとえばIoTデバイスからはAPI Key認証でデータを投入して、Web画面では不特定多数（誰でも）グラフを見れるような設定をする場合は以下のようになります。

```
'データストア名' {
   permit : query, on(push);
   rule : true;
}
'データストア名' {
   permit : push;
   rule : account.key == 'デバイスのAPI_Key';
}
```

詳しくはMilkcocoaの[セキュリティルールについて](https://mlkcca.com/document/security.html)ドキュメントをご覧ください。