Node.js
ifttt
Firebase
IoT
GoogleHome

Google Homeとの連携で利用するFirebase Databaseのセキュリティ設定

はじめに

半額セール!?この機会を逃す手はない!と購入を決めた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=に続けてデータベースのシークレットを指定します。

auth.png

おわりに

やらないよりはマシ程度の内容かなとは思いますが、多少は不安を払拭できたとも思っています。ちょっとした修正で対応できますし...。

Firebaseの認証で利用したデータベースのシークレットは、すでに非推奨の方法ですので、時間が出来たらOAuth2も試してみようと思います。