認証&アクセス制御

先に講義をしてから、このページにてFirebase 操作について、次のページでプログラムを解説します。

Authentication の有効化

firebase console で、構築Authentication を選択してください。開始すると、Sign-in method があると思うので、今回は メール/パスワード を利用します。 「追加のプロバイダ」というのは利用可能な OAuth 認証サービス群ですね。

メール/パスワードの中のメール/パスワード を有効にして保存してください。

そのあとは、上側のタブのUsers からユーザを追加します。 自分の持っている(紛らわしいので firebase 用 google accout とは別の方がいいです)メールアドレスと、「新規につくった」パスワードを登録しましょう。プログラム中に保存したり、間違って露出することもあるでしょうから、他で使っているパスワードは使わないようにしましょう。

認証用 REST API

認証(認可)用 REST API もあり、メールアドレスとパスワードをつかって access token を取得することができます。

  • method: POST
  • URL: https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=...
    • key として渡すのは、firebase project の Web API Key です。
    • firebase コンソールの 「project の概要」横の設定アイコンから「プロジェクトの設定」を確認しましょう。
  • メッセージ本体:以下のような JSON データを送ります。
{
  "returnSecureToken": true,
  "email": "YOUR_EMAIL_ADDRESS",
  "password": "YOUR_PASS_WORD"
}

レスポンスに以下のようなものが返ってくれば正解です。localIduid 相当で、idToken が欲しかったデータです。

{
  ...,
  "localId": "L5ywJTjgrbSiCA0YDdbraawZ9Js2", 
  "email": ...,
  "idToken": ...,
  ...
}

idToken は JWT なので、payload の中身をみてみるとこんな感じ。こちらにも user_id などの形で uid 情報が入っています。 iat, exp は発行時刻や expire ですね。 JWT は firebase 側が発行したサイン付きなので、realtime DB はサインを確認して内容を信頼する訳です。

{
  "iss": ...,
  ...,
  "user_id": ....,
  "sub": ...,
  "iat": ...,
  "exp": ...,
  ...
}

このあたりも、実際に REST API を発行して試してみるとよいでしょう。

Realtime DB + AccessToken

上記で取得したアクセストークンを realtime DB の REST API に付与すれば、realtime DB は利用者の認証情報が利用できるわけです。

GET, POST, PUT などの URL パラーメータに auth=token の形で渡せば大丈夫です。 つまり、URL: https://docs-examples.firebaseio.com/fireblog/users.json だったところを、 https://docs-examples.firebaseio.com/fireblog/users.json?auth=token (token のところは、実際のながーい JWT トークンで置き換え)としてアクセスすれば OK です。

こちらも REST API を発行して試してみるとよいでしょう。

セキュリティルール

Realtime DB のセキュリティルールは、firebase console の「ルール」タブに記載されています。 当初はテストモードで、read, write アクセスが時限ですべて許可されていました。

例えば、

/protected/users/uid0

に書込みできるのは uid0さんだけだけど、 認証済みユーザならどこでも読み込み可能って感じのルールを適用したければ、 セキュリティルールをこんな感じにすれば OK です。

{
  "rules": {
    "protected": {
      "users": {
        "$uid": {
          ".write": "$uid === auth.uid"
        }
      }
    },
    ".read": "auth.uid !== null"
  }
}

詳しいルールはこちらをみてください。