9
10

More than 3 years have passed since last update.

さぁ、firebaseでユーザーが管理者かどうかの判別を行おう!

Last updated at Posted at 2021-01-03

皆さん、「管理者のユーザーだけこのテキスト、ボタンを表示したい」とか、「ユーザーにはこのテキスト、ボタンを表示したい」と思ったこと一度はありますよね???

firebaseの関数firebase.auth().currentUserfirebase.auth().onAuthStateChanged()でユーザーの管理者かどうかを判断するプロパティは存在しないんです。悲しい。。。

なので、firebaseでユーザーの管理者かどうかを判別する方法をご紹介します!!

そんなに難しくないので、是非学習の参考にしてください!

それでは一緒に順を追って説明を見ていきましょう!!(ここからはfirebase-functionsを利用します。firebase-functionsの説明は致しませんのでご了承ください。)

また、この記事を書くにあたってFirebase で公開するウェブサイトに「管理者機能」を付けるを参考にさせて頂きました。ご協力ありがとうございます!

権限を付与する関数を作成

functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp({
    databaseURL: 'YOUR_DATABASE_URL'
})

//ユーザー権限(管理者)付与
exports.addAdminClaim = functions.firestore.document('admin_users/{docID}').onCreate((snap) => {
    const newAdminUser = snap.data();
    if (newAdminUser === undefined) {
        return;
    }
    modifyAdmin(newAdminUser.uid, true);
    //true: 管理者
});

権限を消去する関数を作成

functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');

//ユーザー権限(管理者)付与
exports.addAdminClaim = functions.firestore.document('admin_users/{docID}').onCreate((snap) => {
    const newAdminUser = snap.data();
    if (newAdminUser === undefined) {
        return;
    }
    modifyAdmin(newAdminUser.uid, true);
    //true: 管理者
});

//ユーザー権限(管理者)消去
exports.removeAdminClaim = functions.firestore.document('admin_users/{docID}').onDelete((snap) => {
  const deletedAdminUser = snap.data();
  if (deletedAdminUser === undefined) {
    return;
  }
  modifyAdmin(deletedAdminUser.uid, false);
  //false: 管理者ではないユーザー
});

権限付与・消去を行う関数

functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');

//ユーザー権限(管理者)付与
exports.addAdminClaim = functions.firestore.document('admin_users/{docID}').onCreate((snap) => {
    const newAdminUser = snap.data();
    if (newAdminUser === undefined) {
        return;
    }
    modifyAdmin(newAdminUser.uid, true);
    //true: 管理者
});

//ユーザー権限(管理者)消去
exports.removeAdminClaim = functions.firestore.document('admin_users/{docID}').onDelete((snap) => {
  const deletedAdminUser = snap.data();
  if (deletedAdminUser === undefined) {
    return;
  }
  modifyAdmin(deletedAdminUser.uid, false);
  //false: 管理者ではないユーザー
});

const modifyAdmin = (uid, isAdmin) => {
  admin.auth().setCustomUserClaims(uid, {admin: isAdmin}).then()
}

作成した関数をデプロイ

firebase deploy --only functions

後は、「firebase console」を開き、以下の手順に沿ってコレクションを作成してください。

まず、初めに「Authentication」を開き、管理者の権限を付与したいユーザーの「ユーザー UID」をコピーしてください。(IDではなくユーザー UIDです!間違えないように!!!)

次に、Cloud firestore → コレクションを開始 → コレクションIDに「admin_users」と入力 → ドキュメントIDを作成(自動IDをクリック) → フィールドに「uid」と入力 → タイプは「string」 → 値には先ほどコピーしたUIDをペーストしてください。

これで、設定は終わりです。

あとは、これを判別する関数を呼び出すだけ!

呼び出したいページでgetIdTokenResult()を実行してください。

index.js
firebase.auth().onAuthStateChanged((user) => {
  user.getIdTokenResult(true).then((idTokenResult) => {
        if (idTokenResult.claims.admin) {
          commit("userRights");
        }
      });
})


2021/01/08:追記
「Clound firestore」にて、ルールを追加しないとadminが機能しない事例が発生したので、下記のルールを追加してください。

service cloud.firestore {
  match /databases/{database}/documents {
    match /portfolios/{document=**} {
      allow read;
      allow write: if request.auth.token.admin == true;
    }
    match /skills/{document=**} {
      allow read;
      allow write: if request.auth.token.admin == true;
    }
  }
}

これでidTokenResult.claims.adminの実行結果がtrueならば管理者、falseならユーザーという結果になります。

実際にこのコードをコピペして頂くだけで実行できるかと思います。

色々なところで活用できると思うので、ぜひ使ってください!!!!

以上、「firebaseでユーザーが管理者かどうかの判別を行う方法」でした!!

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい!!

Thank you for reading

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10