Firexport指南

如何在 Firebase Authentication 中設定自訂聲明

自訂聲明(custom claims)是附加在 Firebase 使用者身上的值,例如 admin: true,會隨著使用者的 ID 權杖一起傳送。大多數應用程式都是用它來賦予使用者角色,讓安全性規則和後端能夠檢查。Firebase 控制台無法設定自訂聲明,甚至不會顯示它們:Authentication > 使用者(Users)中沒有任何聲明欄位。自訂聲明要透過 Admin SDK 設定,有三種方法可以做到。哪一種合適,取決於由誰賦予角色,以及多久賦予一次。

更新於 2026年10月27日。 方法 1 中的擴充功能 Firexport 是我們開發的。方法 2 和 3 不需要它。

簡短回答

  • 現在就要為一位或幾位使用者設定角色: 用瀏覽器擴充功能在使用者(Users)分頁中設定。 方法 1
  • 從終端機為許多使用者設定相同的聲明: 一段簡短的 Admin SDK 指令碼。 方法 2
  • 由應用程式自己的管理員指派角色: 一個可呼叫的 Cloud Function。 方法 3
1. 控制台 + 擴充功能2. Admin SDK 指令碼3. Cloud Function
準備工作安裝一個 Chrome 擴充功能,連結你的 Google 帳戶Node.js 和 Google Cloud 憑證一個已部署的函式,以及應用程式中的程式碼
由誰設定聲明你,在控制台中你,在終端機中應用程式的管理員
現有的聲明會顯示出來,除非你刪除,否則都會保留保留,新的聲明會合併進去保留,新的聲明會合併進去
需要啟用計費不需要不需要需要(Blaze 方案)

1. 用 Firexport 在 Firebase 控制台中設定聲明

Firexport 是一款免費的 Chrome 擴充功能,會在 Authentication > 使用者(Users)中每位使用者的 ⋮ 選單裡加入編輯使用者。它的視窗會把使用者的自訂聲明顯示成一列一列可以新增、變更和刪除的項目,與電子郵件、密碼、個人資料和登入供應商並列。它用你連結的 Google 帳戶儲存,所以不需要設定服務帳戶金鑰,也不需要寫程式碼。

  1. 從 Chrome 線上應用程式商店安裝 Firexport。
  2. 在 Firebase 控制台開啟 Authentication > 使用者(Users)。
  3. 將滑鼠游標移到該使用者的那一列上,按一下該列右端的 ⋮,再按一下編輯使用者。
  4. 第一次使用時,視窗會要求你連結 Google 帳戶:選擇已登入控制台的帳戶,並在 Google 的視窗中允許它管理 Firebase Authentication 使用者。
  5. 在自訂聲明下按一下新增聲明,輸入名稱,例如 admin,再選擇類型:string、number、boolean、object、array 或 null。object 和 array 裡面還可以再放更多列。
  6. 按一下儲存。只會儲存你變更的部分,這位使用者的其他聲明都會維持原樣。

視窗會檢查哪些項目

  • 大小。Firebase 每位使用者最多只接受 1,000 位元組的聲明。視窗會在你輸入時計算位元組數,超過上限就不會儲存。
  • 保留名稱。頂層聲明不能使用 Firebase 保留給自己權杖欄位的名稱,例如 sub、aud、exp 或 firebase。視窗會在你儲存之前標示出這類名稱。
  • 其他人所做的變更。如果在你開啟視窗之後這位使用者有了變更,就不會儲存任何內容,你可以讀取最新的值後再試一次。

如果只想查看使用者的聲明而不做任何變更,請按一下該列動作最前面的資訊圖示:它的卡片會列出使用者的完整記錄,包括自訂聲明。要把角色指派給還不存在的使用者,新增使用者按鈕的 ⋮ 選單裡有進階,可以連同其他欄位一起設定聲明。儲存時使用已連結帳戶的權限,這些權限必須包括管理 Firebase Authentication 使用者。你的使用者資料從你的瀏覽器直接送到 Google,從不經過我們。「編輯使用者」在所有方案中都免費。

Firexport 加到 Authentication > 使用者(Users)的使用者詳細資料卡片,靠近底部顯示使用者的自訂聲明:role 為 admin,team 為 support
資訊圖示開啟的卡片會顯示控制台看不到的聲明,這裡是一個角色和一個團隊。

不用指令碼、不用服務帳戶金鑰,直接在控制台設定和查看 Firebase 自訂聲明。

加到 Chrome — 免費

2. 用 Admin SDK 指令碼設定聲明

如果要把相同的聲明指派給許多使用者,或想把它保存在可以再次執行的指令碼中,請在 Node.js 中使用 Firebase Admin SDK。下面這段指令碼接受 JSON 格式的聲明和任意數量的 UID 或電子郵件,並把聲明合併到每位使用者現有的聲明中。它需要一個能管理使用者的帳戶:專案 Owner 或 Editor,或者 Firebase Authentication Admin 角色。

  1. 安裝 SDK:npm install firebase-admin
  2. 登入以取得本機憑證:gcloud auth application-default login。在伺服器上,改為讓 GOOGLE_APPLICATION_CREDENTIALS 指向服務帳戶金鑰。
  3. 把下面的指令碼存成 set-claims.mjs,替換 your-project-id,然後執行 node set-claims.mjs '{"admin":true}' maya@example.com。
// Usage: node set-claims.mjs '{"admin":true}' maya@example.com u2   → adds admin: true to each user's claims
// Users are UIDs or emails. The claims you pass are merged into the ones each user has; null removes one.
import { initializeApp } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';

initializeApp({ projectId: 'your-project-id' });
const auth = getAuth();
const [json, ...users] = process.argv.slice(2);
if (!json || !users.length) throw new Error(`Usage: node set-claims.mjs '{"admin":true}' <uid or email> ...`);
const changes = JSON.parse(json);
if (typeof changes !== 'object' || changes === null || Array.isArray(changes)) throw new Error('Pass the claims as a JSON object');

for (const who of users) {
  const user = who.includes('@') ? await auth.getUserByEmail(who) : await auth.getUser(who);
  // setCustomUserClaims() replaces every claim the user has, so start from the current ones.
  const claims = { ...user.customClaims, ...changes };
  for (const [name, value] of Object.entries(claims)) if (value === null) delete claims[name];
  await auth.setCustomUserClaims(user.uid, claims);
  console.log(`${who}: ${JSON.stringify(claims)}`);
}
  • setCustomUserClaims() 會用你傳入的內容取代使用者的所有聲明。這就是指令碼先讀取目前聲明的原因:如果只傳入 {"admin":true} 呼叫它,其他聲明都會被刪除。
  • 值為 null 會移除該聲明,所以 {"admin":null} 會收回這個角色。
  • 聲明超過 1,000 位元組或使用保留名稱時,Admin SDK 會擲回錯誤,該使用者會保留原本的聲明。

3. 用 Cloud Function 讓應用程式的管理員設定聲明

當角色是應用程式的一部分時,例如在管理畫面中指派版主,Admin SDK 就必須在你掌控的伺服器上執行。通常會放在可呼叫的 Cloud Function 中。下面這個函式讓權杖中已經有 admin: true 的使用者為其他使用者設定聲明。部署函式需要 Blaze 方案。

// functions/index.js: a callable function your app's admin screen calls as setClaims({ uid, claims })
const { onCall, HttpsError } = require('firebase-functions/v2/https');
const { initializeApp } = require('firebase-admin/app');
const { getAuth } = require('firebase-admin/auth');

initializeApp();

exports.setClaims = onCall(async (request) => {
  // Only a user whose token already says admin: true may change claims. Give the first admin theirs another way.
  if (request.auth?.token.admin !== true) throw new HttpsError('permission-denied', 'Only admins can set claims');
  const { uid, claims } = request.data;
  const user = await getAuth().getUser(uid);
  const next = { ...user.customClaims, ...claims }; // setCustomUserClaims() replaces them all, so keep the others
  await getAuth().setCustomUserClaims(uid, next);
  return { uid, claims: next };
});

用 firebase deploy --only functions 部署,然後從應用程式呼叫它:

import { getFunctions, httpsCallable } from 'firebase/functions';

await httpsCallable(getFunctions(), 'setClaims')({ uid: 'u1', claims: { editor: true } });

總得有人當第一位管理員。請用方法 1 或 2 為那一個帳戶設定 admin 聲明。

新的聲明何時生效,以及如何使用

聲明存放在 ID 權杖中,而 Firebase 大約每小時重新整理一次權杖。使用者會在下次重新整理或下次登入時取得新的聲明。若要立即取得,應用程式可以對已登入的使用者呼叫 getIdToken(true),再用 getIdTokenResult() 讀取聲明。安全性規則則從 request.auth.token 讀取它們:

match /posts/{postId} {
  allow read: if true;
  allow write: if request.auth != null && request.auth.token.admin == true;
}
  • 聲明是用來控管存取權的,而不是用來存放個人資料。它們會隨每個要求一起傳送,而且 Firebase 將它們限制在 1,000 位元組以內。
  • 使用者只要解碼自己的權杖,就能讀到自己的聲明,所以不要在其中放入機密資訊。
  • 要把每位使用者的聲明集中到一個檔案中,請匯出使用者。匯出 Firebase Auth 使用者的指南介紹了三種方法。

常見問題

可以在 Firebase 控制台中設定自訂聲明嗎?

只用控制台做不到。Authentication > 使用者(Users)沒有自訂聲明的欄位,也不會顯示它們。要設定自訂聲明,必須在指令碼、伺服器或 Cloud Function 中使用 Admin SDK,或使用 Firexport 這類瀏覽器擴充功能,它會在使用者(Users)分頁加入「編輯使用者」。

如何查看使用者的自訂聲明?

控制台不會顯示它們。使用 Admin SDK 時,getUser(uid) 會以 customClaims 回傳它們。在應用程式中,getIdTokenResult() 會以 claims 回傳已登入使用者的聲明。Firexport 會在 Authentication > 使用者(Users)每一列的資訊卡片上顯示它們。

為什麼我的應用程式看不到新的自訂聲明?

聲明是從 ID 權杖讀取的,而使用者目前的權杖是在你設定聲明之前核發的。Firebase 會在一小時內重新整理權杖,重新登入也會取得新的權杖。若要立即取得新的聲明,請對已登入的使用者呼叫 getIdToken(true)。

setCustomUserClaims 會取代現有的聲明嗎?

會。它會把使用者的聲明設定成和你傳入的物件完全相同,所以不在其中的聲明都會被移除。請先用 getUser() 讀取目前的聲明,再把你的變更合併進去,就像上面的指令碼那樣。傳入 null 則會移除所有聲明。

Firebase 自訂聲明最大可以多大?

一位使用者的所有聲明合計最多 1,000 位元組(以 JSON 計算)。Firebase 用於自己權杖欄位的頂層名稱是保留名稱:acr、amr、at_hash、aud、auth_time、azp、cnf、c_hash、exp、firebase、iat、iss、jti、nbf、nonce 和 sub。