はじめに
半額セール!?この機会を逃す手はない!と購入を決めたGoogle Home Mini。
Google Home、IFTTT、Firebase、Node.js、irMagicianを使ってシーリングライトを音声操作する
の記事を参考に、Google Home→IFTTT→Firebaseを経由して、Realtime Databaseの更新イベントをフックしているラズパイから、家電操作などができるようになりました(ありがとうございます)。
その際、誰もがFirebaseのDatabaseに書き込める状態というのに一抹の不安を感じたので、Databaseのセキュリティ設定について、少しあがいてみることにしました。
Firebaseの設定
データ
FirebaseのDatabaseは、参照先の記事 同様、以下のように作成しています。
プロジェクト名-xxxxx
└ googlehome
└ word: ""
第三者にwordの値を更新されてしまうと困るので、この書き込みを制限することが目標です。
しかし、参照先の実装 のように、Realtime Databaseの更新イベントのフック処理を
var firebase = require("firebase");
var config = {
//省略
};
firebase.initializeApp(config);
const path = "/googlehome";
const key = "word";
const db = firebase.database();
db.ref(path).on("value", function(changedSnapshot) {
const value = changedSnapshot.child(key).val();
if (value) {
//省略(wordの値に応じた家電操作など)
db.ref(path).set({[key]: ""}); //wordの値をクリア
}
});
とする場合、googlehome以下に対して書き込み権限が必要となるようで、さて、どうしようかなと...。
ルール
そこで、以下のようにルールを設定しました。
{
"rules": {
".read": false,
".write": false,
"googlehome": {
".read": true,
".write": true,
"word": {
".validate": "(auth != null || newData.val() === '')"
}
}
}
}
こうすることで、wordの値に文字列を設定するには認証が必要となります。また、googlehome以下に書き込み権限があるので、上記フック処理もそのままの実装で動作します。(ルール内で、誰でも空文字を設定できるようにしているのは、フック処理内でwordの値をクリア可能とするためです)
Firebaseの認証
残りはIFTTT→Firebaseの連携で認証を追加すれば終わりです。簡単に対応するため...、まずは GoogleHomeとiftttとDialogflowとfirebaseとLINEBOTとラズパイを使って子供と音声によるLINE交換をしてみる(後編) 内の FirebaseのRESTによる認証 を参考に、データベースのシークレットを利用して認証することにしました。
Webhooksレシピ
IFTTTのWebリクエストのURLの最後で、auth=に続けてデータベースのシークレットを指定します。
おわりに
やらないよりはマシ程度の内容かなとは思いますが、多少は不安を払拭できたとも思っています。ちょっとした修正で対応できますし...。
Firebaseの認証で利用したデータベースのシークレットは、すでに非推奨の方法ですので、時間が出来たらOAuth2も試してみようと思います。