サービスの管理者でも、全権限がある人や、アルバイトで一時的に入った人など、細かく権限を設定したいものです。
Firebase Authのカスタムクレームという機能を使えば、細かい権限設定が行えます。
しかし、その登録はAdmin SDKを介するので、NodeのRepl環境で行うのは、認証情報の初期化がややこしいです。
個人的にかなりつまづいたので、共有させていただきます。
localのfunctionsディレクトリでNodeを起動
まず、ターミナルでfunctions/
のディレクトリに移動してNode Replを起動します。
cd XXX/functions/
node
サービスアカウントの秘密鍵を作成
- Firebase Consoleのプロジェクトの設定に移動する
- サービスアカウント のタブを開く
- 秘密鍵を生成してダウンロードして、保存したパスをコピーしておく
サービスアカウントの秘密鍵のパスを環境変数に設定
export GOOGLE_APPLICATION_CREDENTIALS='PRIVATE_KEY_PASS'
これにて、自動でAdmin SDKが認証情報を取り扱ってくれます。
公式ドキュメントによると、これ以外の方法である認証情報をハードコードすることは推奨されていません。
Admin SDKが正しく初期化できることを確認する
const admin = require('firebase-admin');
admin.initializeApp();
カスタムクレームが既に存在するか確認
該当ユーザにカスタムクレームが既に追加されているか確認しましょう。
これは、Admin SDKから行えるカスタムクレームへの操作が、既存のカスタムクレームに対する上書き操作であるからです。
const uid = 'XXXXXXXX';
auth.getUser(uid).then((res,rej)=>{console.log(res.customClaims)});
このconsole出力がundefined
なら、該当ユーザに対するカスタムクレームは追加されていないことを示します。
一方で、以下のようなオブジェクトが出力される場合は、カスタムクレームが既に存在するので、値を追加する場合は、既にある存在を保持しつつ値を使いするように注意する必要があります。
{ role: { tempStaff: true } }
ですので、これらの既にあるkey,valueのペアを保存し統合された値を上書きするということをお勧めします。
let savedCustomClaimObject = { role: { tempStaff: true } };
savedCustomClaimObject.newKey = newValue;
admin.auth().setCustomUserClaims(uid, savedCustomClaimObject)
トラブルシューティング based on my failures
Error: Cannot find module 'firebase-admin'
Error: Cannot find module 'firebase-admin'
Require stack:
- <repl>
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:794:15)
at Function.Module._load (internal/modules/cjs/loader.js:687:27)
at Module.require (internal/modules/cjs/loader.js:849:19)
at require (internal/modules/cjs/helpers.js:74:18) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '<repl>' ]
解決策: ディレクトリを確認
ローカルのfunctionsのディレクトリに移動してることを確認しましょう。このディレクトリでnode
起動する必要があります。
Error: Failed to determine project ID
> (node:6503) UnhandledPromiseRejectionWarning:
Error: Failed to determine project ID:
Error while making request: getaddrinfo ENOTFOUND metadata.google.internal.
Error code: ENOTFOUND
at FirebaseAppError.FirebaseError [as constructor]
...
解決策:秘密鍵の環境変数を再確認しよう
これが全てとは限りませんが、再度export GOOGLE_APPLICATION_CREDENTIALS ...
の操作を実行しましょう。環境変数は現在のシェルのセッションのみで有効なので、違うターミナルウィンドウ開いた時は、再度環境変数を入れる必要があるので要注意です。
References
公式ドキュメントしか勝たん