認証&アクセス制御

先に講義をしてから、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 トークンで置き換え, docs-example ってのは、仮の名前なのは大丈夫だよね?)としてアクセスすれば 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"
  }
}

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

プログラム

例のごとく、git pull してください。あと、ライブラリの追加 (JWT) があったので、Project を右クリックして、mavenproject reload しておきましょう。

kobeU.cs.samplesNet.fbRealtimeDB.auth 以下に配置しています。前より、一段 directory が深くなっているので、気を付けてください。

実行前に以下の箇所を変更してください。

  • プログラム
    • TokenManager
      • webAPIKey: 取得した firebase project の web API key を入力してください。
    • SampleCaller
      • baseURL: 各自の Realtime DB の base URL を入力してください。
  • 一般ファイル
    • /account/request.json: 実験で利用するアカウントのメールアドレスとパスワードを記入してください。

プログラムの簡単な解説

  • TokenManager: getToken(), getTokenUser() などを提供

    • /account/request.json の情報をつかって認証をおこなう。一度取得したトークンは /account/token.jwt に配置する。
    • getToken(): 利用可能なトークンを返す。すでにトークンを持っている場合は、再利用するが、expire されている場合は再取得する。
    • getTokenUser(): トークンを利用したユーザの firebase における user id を返す。セキュリティルールの auth.uid に相当する。
  • UserDBService: 前回同様、RealtimeDBにアクセスするメソッド。

    • get(), put()のパラメータに token が加わる
  • SampleCaller: 簡単なサンプルプログラムです。

    • まず、TokenManager.getManager()TokenManager を取得し、getToken(), getTokenUser() でトークンおよび uid を取得する。
    • あとは、前回同様 UserDBService にアクセスするだけ。

練習問題

  • 直接 REST API をたたいて (postman などをつかって)、token の取得、アクセス制御の確認をしてみましょう。

  • プログラムを介して、アクセス制御の確認をしてみましょう。

    • いくつかデータを準備して、読み書きできる場所へのアクセスが可能であることを確認する。
    • 読み書き出来ない場所へのアクセスが拒否されることを確認する

Read more