Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

ควบคุมการเข้าถึงด้วยการอ้างสิทธิ์ที่กำหนดเองและกฎความปลอดภัย

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

Firebase Admin SDK รองรับการกำหนดแอตทริบิวต์ที่กำหนดเองในบัญชีผู้ใช้ ซึ่งช่วยให้สามารถใช้กลยุทธ์การควบคุมการเข้าถึงต่างๆ รวมถึงการควบคุมการเข้าถึงตามบทบาทในแอป Firebase แอตทริบิวต์ที่กำหนดเองเหล่านี้สามารถให้สิทธิ์การเข้าถึง (บทบาท) ในระดับต่างๆ แก่ผู้ใช้ ซึ่งบังคับใช้ในกฎความปลอดภัยของแอปพลิเคชัน

สามารถกำหนดบทบาทของผู้ใช้สำหรับกรณีทั่วไปต่อไปนี้:

  • ให้สิทธิ์ผู้ดูแลระบบแก่ผู้ใช้ในการเข้าถึงข้อมูลและทรัพยากร
  • การกำหนดกลุ่มต่างๆ ที่ผู้ใช้เป็นสมาชิก
  • ให้การเข้าถึงหลายระดับ:
    • ความแตกต่างของสมาชิกแบบชำระเงิน/ไม่ชำระเงิน
    • สร้างความแตกต่างระหว่างผู้ดูแลจากผู้ใช้ทั่วไป
    • ใบสมัครครู/นักเรียน ฯลฯ
  • เพิ่มตัวระบุเพิ่มเติมเกี่ยวกับผู้ใช้ ตัวอย่างเช่น ผู้ใช้ Firebase สามารถจับคู่กับ UID อื่นในระบบอื่นได้

ลองพิจารณากรณีที่คุณต้องการจำกัดการเข้าถึงโหนดฐานข้อมูล "adminContent" คุณสามารถทำได้ด้วยการค้นหาฐานข้อมูลในรายชื่อผู้ดูแลระบบ อย่างไรก็ตาม คุณสามารถบรรลุวัตถุประสงค์เดียวกันได้อย่างมีประสิทธิภาพมากขึ้นโดยใช้การอ้างสิทธิ์ผู้ใช้แบบกำหนดเองที่ชื่อว่า admin ด้วยกฎ Realtime Database ต่อไปนี้:

{
  "rules": {
    "adminContent": {
      ".read": "auth.token.admin === true",
      ".write": "auth.token.admin === true",
    }
  }
}

การอ้างสิทธิ์ผู้ใช้แบบกำหนดเองสามารถเข้าถึงได้ผ่านโทเค็นการตรวจสอบสิทธิ์ของผู้ใช้ ในตัวอย่างข้างต้น เฉพาะผู้ใช้ที่ตั้งค่า admin เป็น true ในการอ้างสิทธิ์โทเค็นเท่านั้นที่จะมีสิทธิ์อ่าน/เขียนโหนด adminContent เนื่องจากโทเค็น ID มีการยืนยันเหล่านี้อยู่แล้ว จึงไม่จำเป็นต้องดำเนินการหรือค้นหาเพิ่มเติมเพื่อตรวจสอบสิทธิ์ของผู้ดูแลระบบ นอกจากนี้ โทเค็น ID ยังเป็นกลไกที่เชื่อถือได้สำหรับการอ้างสิทธิ์ที่กำหนดเองเหล่านี้ การเข้าถึงที่ผ่านการตรวจสอบสิทธิ์ทั้งหมดต้องตรวจสอบโทเค็น ID ก่อนดำเนินการตามคำขอที่เกี่ยวข้อง

ตัวอย่างโค้ดและวิธีแก้ปัญหาที่อธิบายไว้ในหน้านี้มาจากทั้ง Firebase Auth API ฝั่งไคลเอ็นต์และ Auth API ฝั่งเซิร์ฟเวอร์ที่ Admin SDK จัดเตรียมให้

ตั้งค่าและตรวจสอบการอ้างสิทธิ์ผู้ใช้ที่กำหนดเองผ่าน Admin SDK

การอ้างสิทธิ์ที่กำหนดเองอาจมีข้อมูลที่ละเอียดอ่อน ดังนั้น Firebase Admin SDK จึงควรตั้งค่าจากสภาพแวดล้อมเซิร์ฟเวอร์ที่มีสิทธิพิเศษเท่านั้น

Node.js

// Set admin privilege on the user corresponding to uid.

getAuth()
  .setCustomUserClaims(uid, { admin: true })
  .then(() => {
    // The new custom claims will propagate to the user's ID token the
    // next time a new one is issued.
  });

Java

// Set admin privilege on the user corresponding to uid.
Map<String, Object> claims = new HashMap<>();
claims.put("admin", true);
FirebaseAuth.getInstance().setCustomUserClaims(uid, claims);
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.

Python

# Set admin privilege on the user corresponding to uid.
auth.set_custom_user_claims(uid, {'admin': True})
# The new custom claims will propagate to the user's ID token the
# next time a new one is issued.

ไป

// Get an auth client from the firebase.App
client, err := app.Auth(ctx)
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

// Set admin privilege on the user corresponding to uid.
claims := map[string]interface{}{"admin": true}
err = client.SetCustomUserClaims(ctx, uid, claims)
if err != nil {
	log.Fatalf("error setting custom claims %v\n", err)
}
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.

ค#

// Set admin privileges on the user corresponding to uid.
var claims = new Dictionary<string, object>()
{
    { "admin", true },
};
await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(uid, claims);
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.

ออบเจ็กต์การอ้างสิทธิ์ที่กำหนดเองไม่ควรมีชื่อคีย์ที่สงวนไว้ ของ OIDC หรือ ชื่อที่สงวนไว้ของ Firebase เพย์โหลดการอ้างสิทธิ์ที่กำหนดเองต้องไม่เกิน 1,000 ไบต์

โทเค็น ID ที่ส่งไปยังเซิร์ฟเวอร์แบ็กเอนด์สามารถยืนยันตัวตนของผู้ใช้และระดับการเข้าถึงโดยใช้ Admin SDK ได้ดังนี้

Node.js

// Verify the ID token first.
getAuth()
  .verifyIdToken(idToken)
  .then((claims) => {
    if (claims.admin === true) {
      // Allow access to requested admin resource.
    }
  });

Java

// Verify the ID token first.
FirebaseToken decoded = FirebaseAuth.getInstance().verifyIdToken(idToken);
if (Boolean.TRUE.equals(decoded.getClaims().get("admin"))) {
  // Allow access to requested admin resource.
}

Python

# Verify the ID token first.
claims = auth.verify_id_token(id_token)
if claims['admin'] is True:
    # Allow access to requested admin resource.
    pass

ไป

// Verify the ID token first.
token, err := client.VerifyIDToken(ctx, idToken)
if err != nil {
	log.Fatal(err)
}

claims := token.Claims
if admin, ok := claims["admin"]; ok {
	if admin.(bool) {
		//Allow access to requested admin resource.
	}
}

ค#

// Verify the ID token first.
FirebaseToken decoded = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
object isAdmin;
if (decoded.Claims.TryGetValue("admin", out isAdmin))
{
    if ((bool)isAdmin)
    {
        // Allow access to requested admin resource.
    }
}

คุณยังสามารถตรวจสอบการอ้างสิทธิ์แบบกำหนดเองที่มีอยู่ของผู้ใช้ ซึ่งมีให้ใช้งานเป็นพร็อพเพอร์ตี้บนออบเจ็กต์ผู้ใช้:

Node.js

// Lookup the user associated with the specified uid.
getAuth()
  .getUser(uid)
  .then((userRecord) => {
    // The claims can be accessed on the user record.
    console.log(userRecord.customClaims['admin']);
  });

Java

// Lookup the user associated with the specified uid.
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
System.out.println(user.getCustomClaims().get("admin"));

Python

# Lookup the user associated with the specified uid.
user = auth.get_user(uid)
# The claims can be accessed on the user record.
print(user.custom_claims.get('admin'))

ไป

// Lookup the user associated with the specified uid.
user, err := client.GetUser(ctx, uid)
if err != nil {
	log.Fatal(err)
}
// The claims can be accessed on the user record.
if admin, ok := user.CustomClaims["admin"]; ok {
	if admin.(bool) {
		log.Println(admin)
	}
}

ค#

// Lookup the user associated with the specified uid.
UserRecord user = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
Console.WriteLine(user.CustomClaims["admin"]);

คุณสามารถลบการอ้างสิทธิ์ที่กำหนดเองของผู้ใช้โดยส่งค่า null สำหรับ customClaims

เผยแพร่การอ้างสิทธิ์ที่กำหนดเองไปยังลูกค้า

หลังจากแก้ไขการอ้างสิทธิ์ใหม่บนผู้ใช้ผ่าน Admin SDK แล้ว การอ้างสิทธิ์ดังกล่าวจะเผยแพร่ไปยังผู้ใช้ที่ตรวจสอบสิทธิ์ในฝั่งไคลเอ็นต์ผ่านโทเค็น ID ด้วยวิธีต่อไปนี้:

  • ผู้ใช้ลงชื่อเข้าใช้หรือตรวจสอบอีกครั้งหลังจากแก้ไขการอ้างสิทธิ์ที่กำหนดเอง โทเค็น ID ที่ออกตามผลลัพธ์จะมีการอ้างสิทธิ์ล่าสุด
  • เซสชันผู้ใช้ที่มีอยู่ได้รับการรีเฟรชโทเค็น ID หลังจากโทเค็นเก่าหมดอายุ
  • โทเค็น ID ถูกบังคับให้รีเฟรชโดยการเรียก currentUser.getIdToken(true)

เข้าถึงการเรียกร้องที่กำหนดเองในไคลเอนต์

สามารถเรียกข้อมูลการอ้างสิทธิ์ที่กำหนดเองได้ผ่านโทเค็น ID ของผู้ใช้เท่านั้น การเข้าถึงการอ้างสิทธิ์เหล่านี้อาจจำเป็นต้องแก้ไข UI ของไคลเอ็นต์ตามบทบาทของผู้ใช้หรือระดับการเข้าถึง อย่างไรก็ตาม ควรบังคับใช้การเข้าถึงแบ็กเอนด์ผ่านโทเค็น ID หลังจากตรวจสอบและแยกวิเคราะห์การอ้างสิทธิ์ ไม่ควรส่งการอ้างสิทธิ์ที่กำหนดเองไปยังแบ็กเอนด์โดยตรง เนื่องจากไม่สามารถเชื่อถือนอกโทเค็นได้

เมื่อการอ้างสิทธิ์ล่าสุดแพร่กระจายไปยังโทเค็น ID ของผู้ใช้ คุณสามารถรับได้โดยดึงโทเค็น ID:

JavaScript

firebase.auth().currentUser.getIdTokenResult()
  .then((idTokenResult) => {
     // Confirm the user is an Admin.
     if (!!idTokenResult.claims.admin) {
       // Show admin UI.
       showAdminUI();
     } else {
       // Show regular user UI.
       showRegularUI();
     }
  })
  .catch((error) => {
    console.log(error);
  });

Android

user.getIdToken(false).addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
  @Override
  public void onSuccess(GetTokenResult result) {
    boolean isAdmin = result.getClaims().get("admin");
    if (isAdmin) {
      // Show admin UI.
      showAdminUI();
    } else {
      // Show regular user UI.
      showRegularUI();
    }
  }
});

Swift

user.getIDTokenResult(completion: { (result, error) in
  guard let admin = result?.claims?["admin"] as? NSNumber else {
    // Show regular user UI.
    showRegularUI()
    return
  }
  if admin.boolValue {
    // Show admin UI.
    showAdminUI()
  } else {
    // Show regular user UI.
    showRegularUI()
  }
})

วัตถุประสงค์-C

user.getIDTokenResultWithCompletion:^(FIRAuthTokenResult *result,
                                      NSError *error) {
  if (error != nil) {
    BOOL *admin = [result.claims[@"admin"] boolValue];
    if (admin) {
      // Show admin UI.
      [self showAdminUI];
    } else {
      // Show regular user UI.
      [self showRegularUI];
    }
  }
}];

แนวทางปฏิบัติที่ดีที่สุดสำหรับการอ้างสิทธิ์ที่กำหนดเอง

การอ้างสิทธิ์แบบกำหนดเองจะใช้เพื่อให้การควบคุมการเข้าถึงเท่านั้น ไม่ได้ออกแบบมาเพื่อเก็บข้อมูลเพิ่มเติม (เช่น โปรไฟล์และข้อมูลที่กำหนดเองอื่นๆ) แม้ว่าวิธีนี้อาจดูเหมือนเป็นกลไกที่สะดวกในการดำเนินการ แต่ก็ไม่แนะนำอย่างยิ่งเนื่องจากการอ้างสิทธิ์เหล่านี้จัดเก็บไว้ในโทเค็น ID และอาจทำให้เกิดปัญหาด้านประสิทธิภาพเนื่องจากคำขอที่ตรวจสอบสิทธิ์ทั้งหมดจะมีโทเค็น Firebase ID ที่สอดคล้องกับผู้ใช้ที่ลงชื่อเข้าใช้เสมอ

  • ใช้การอ้างสิทธิ์ที่กำหนดเองเพื่อจัดเก็บข้อมูลเพื่อควบคุมการเข้าถึงของผู้ใช้เท่านั้น ข้อมูลอื่นๆ ทั้งหมดควรจัดเก็บแยกจากกันผ่านฐานข้อมูลแบบเรียลไทม์หรือที่จัดเก็บข้อมูลฝั่งเซิร์ฟเวอร์อื่นๆ
  • การอ้างสิทธิ์แบบกำหนดเองมีขนาดจำกัด การผ่านเพย์โหลดการอ้างสิทธิ์ที่กำหนดเองที่มากกว่า 1,000 ไบต์จะเกิดข้อผิดพลาด

ตัวอย่างและกรณีการใช้งาน

ตัวอย่างต่อไปนี้แสดงการอ้างสิทธิ์ที่กำหนดเองในบริบทของกรณีการใช้งาน Firebase ที่เฉพาะเจาะจง

การกำหนดบทบาทผ่านฟังก์ชัน Firebase ในการสร้างผู้ใช้

ในตัวอย่างนี้ การอ้างสิทธิ์ที่กำหนดเองถูกกำหนดให้กับผู้ใช้ในการสร้างโดยใช้ Cloud Functions

สามารถเพิ่มการอ้างสิทธิ์แบบกำหนดเองได้โดยใช้ Cloud Functions และเผยแพร่ทันทีด้วย Realtime Database ฟังก์ชันนี้ถูกเรียกใช้เมื่อสมัครใช้งานโดยใช้ทริกเกอร์ onCreate เท่านั้น เมื่อตั้งค่าการอ้างสิทธิ์ที่กำหนดเองแล้ว จะเผยแพร่ไปยังเซสชันที่มีอยู่และในอนาคตทั้งหมด ครั้งถัดไปที่ผู้ใช้ลงชื่อเข้าใช้ด้วยข้อมูลรับรองผู้ใช้ โทเค็นจะมีการอ้างสิทธิ์ที่กำหนดเอง

การใช้งานฝั่งไคลเอ็นต์ (JavaScript)

const provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider)
.catch(error => {
  console.log(error);
});

let callback = null;
let metadataRef = null;
firebase.auth().onAuthStateChanged(user => {
  // Remove previous listener.
  if (callback) {
    metadataRef.off('value', callback);
  }
  // On user login add new listener.
  if (user) {
    // Check if refresh is required.
    metadataRef = firebase.database().ref('metadata/' + user.uid + '/refreshTime');
    callback = (snapshot) => {
      // Force refresh to pick up the latest custom claims changes.
      // Note this is always triggered on first call. Further optimization could be
      // added to avoid the initial trigger when the token is issued and already contains
      // the latest claims.
      user.getIdToken(true);
    };
    // Subscribe new listener to changes on that node.
    metadataRef.on('value', callback);
  }
});

ตรรกะของฟังก์ชันคลาวด์

เพิ่มโหนดฐานข้อมูลใหม่ (ข้อมูลเมตา/($uid)} ที่จำกัดการอ่าน/เขียนสำหรับผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์แล้ว

const functions = require('firebase-functions');
const { initializeApp } = require('firebase-admin/app');
const { getAuth } = require('firebase-admin/auth');
const { getDatabase } = require('firebase-admin/database');

initializeApp();

// On sign up.
exports.processSignUp = functions.auth.user().onCreate(async (user) => {
  // Check if user meets role criteria.
  if (
    user.email &&
    user.email.endsWith('@admin.example.com') &&
    user.emailVerified
  ) {
    const customClaims = {
      admin: true,
      accessLevel: 9
    };

    try {
      // Set custom user claims on this newly created user.
      await getAuth().setCustomUserClaims(user.uid, customClaims);

      // Update real-time database to notify client to force refresh.
      const metadataRef = getDatabase().ref('metadata/' + user.uid);

      // Set the refresh time to the current UTC timestamp.
      // This will be captured on the client to force a token refresh.
      await  metadataRef.set({refreshTime: new Date().getTime()});
    } catch (error) {
      console.log(error);
    }
  }
});

กฎของฐานข้อมูล

{
  "rules": {
    "metadata": {
      "$user_id": {
        // Read access only granted to the authenticated user.
        ".read": "$user_id === auth.uid",
        // Write access only via Admin SDK.
        ".write": false
      }
    }
  }
}

การกำหนดบทบาทผ่านคำขอ HTTP

ตัวอย่างต่อไปนี้ตั้งค่าการอ้างสิทธิ์ผู้ใช้ที่กำหนดเองกับผู้ใช้ที่ลงชื่อเข้าใช้ใหม่ผ่านคำขอ HTTP

การใช้งานฝั่งไคลเอ็นต์ (JavaScript)

const provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider)
.then((result) => {
  // User is signed in. Get the ID token.
  return result.user.getIdToken();
})
.then((idToken) => {
  // Pass the ID token to the server.
  $.post(
    '/setCustomClaims',
    {
      idToken: idToken
    },
    (data, status) => {
      // This is not required. You could just wait until the token is expired
      // and it proactively refreshes.
      if (status == 'success' && data) {
        const json = JSON.parse(data);
        if (json && json.status == 'success') {
          // Force token refresh. The token claims will contain the additional claims.
          firebase.auth().currentUser.getIdToken(true);
        }
      }
    });
}).catch((error) => {
  console.log(error);
});

การใช้งานแบ็กเอนด์ (Admin SDK)

app.post('/setCustomClaims', async (req, res) => {
  // Get the ID token passed.
  const idToken = req.body.idToken;

  // Verify the ID token and decode its payload.
  const claims = await getAuth().verifyIdToken(idToken);

  // Verify user is eligible for additional privileges.
  if (
    typeof claims.email !== 'undefined' &&
    typeof claims.email_verified !== 'undefined' &&
    claims.email_verified &&
    claims.email.endsWith('@admin.example.com')
  ) {
    // Add custom claims for additional privileges.
    await getAuth().setCustomUserClaims(claims.sub, {
      admin: true
    });

    // Tell client to refresh token on user.
    res.end(JSON.stringify({
      status: 'success'
    }));
  } else {
    // Return nothing.
    res.end(JSON.stringify({ status: 'ineligible' }));
  }
});

สามารถใช้โฟลว์เดียวกันนี้เมื่ออัปเกรดระดับการเข้าถึงของผู้ใช้ที่มีอยู่ ตัวอย่างเช่น ผู้ใช้ฟรีอัปเกรดเป็นการสมัครแบบชำระเงิน โทเค็น ID ของผู้ใช้จะถูกส่งพร้อมกับข้อมูลการชำระเงินไปยังเซิร์ฟเวอร์ส่วนหลังผ่านคำขอ HTTP เมื่อประมวลผลการชำระเงินสำเร็จแล้ว ผู้ใช้จะถูกตั้งค่าให้เป็นสมาชิกแบบชำระเงินผ่าน Admin SDK การตอบสนอง HTTP ที่สำเร็จจะส่งคืนไปยังไคลเอนต์เพื่อบังคับให้รีเฟรชโทเค็น

การกำหนดบทบาทผ่านสคริปต์แบ็กเอนด์

สคริปต์ที่เกิดซ้ำ (ไม่ได้เริ่มต้นจากไคลเอนต์) สามารถตั้งค่าให้รันเพื่ออัปเดตการอ้างสิทธิ์ที่กำหนดเองของผู้ใช้:

Node.js

getAuth()
  .getUserByEmail('user@admin.example.com')
  .then((user) => {
    // Confirm user is verified.
    if (user.emailVerified) {
      // Add custom claims for additional privileges.
      // This will be picked up by the user on token refresh or next sign in on new device.
      return getAuth().setCustomUserClaims(user.uid, {
        admin: true,
      });
    }
  })
  .catch((error) => {
    console.log(error);
  });

Java

UserRecord user = FirebaseAuth.getInstance()
    .getUserByEmail("user@admin.example.com");
// Confirm user is verified.
if (user.isEmailVerified()) {
  Map<String, Object> claims = new HashMap<>();
  claims.put("admin", true);
  FirebaseAuth.getInstance().setCustomUserClaims(user.getUid(), claims);
}

Python

user = auth.get_user_by_email('user@admin.example.com')
# Confirm user is verified
if user.email_verified:
    # Add custom claims for additional privileges.
    # This will be picked up by the user on token refresh or next sign in on new device.
    auth.set_custom_user_claims(user.uid, {
        'admin': True
    })

ไป

user, err := client.GetUserByEmail(ctx, "user@admin.example.com")
if err != nil {
	log.Fatal(err)
}
// Confirm user is verified
if user.EmailVerified {
	// Add custom claims for additional privileges.
	// This will be picked up by the user on token refresh or next sign in on new device.
	err := client.SetCustomUserClaims(ctx, user.UID, map[string]interface{}{"admin": true})
	if err != nil {
		log.Fatalf("error setting custom claims %v\n", err)
	}

}

ค#

UserRecord user = await FirebaseAuth.DefaultInstance
    .GetUserByEmailAsync("user@admin.example.com");
// Confirm user is verified.
if (user.EmailVerified)
{
    var claims = new Dictionary<string, object>()
    {
        { "admin", true },
    };
    await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(user.Uid, claims);
}

การอ้างสิทธิ์ที่กำหนดเองสามารถแก้ไขเพิ่มเติมได้ผ่าน Admin SDK:

Node.js

getAuth()
  .getUserByEmail('user@admin.example.com')
  .then((user) => {
    // Add incremental custom claim without overwriting existing claims.
    const currentCustomClaims = user.customClaims;
    if (currentCustomClaims['admin']) {
      // Add level.
      currentCustomClaims['accessLevel'] = 10;
      // Add custom claims for additional privileges.
      return getAuth().setCustomUserClaims(user.uid, currentCustomClaims);
    }
  })
  .catch((error) => {
    console.log(error);
  });

Java

UserRecord user = FirebaseAuth.getInstance()
    .getUserByEmail("user@admin.example.com");
// Add incremental custom claim without overwriting the existing claims.
Map<String, Object> currentClaims = user.getCustomClaims();
if (Boolean.TRUE.equals(currentClaims.get("admin"))) {
  // Add level.
  currentClaims.put("level", 10);
  // Add custom claims for additional privileges.
  FirebaseAuth.getInstance().setCustomUserClaims(user.getUid(), currentClaims);
}

Python

user = auth.get_user_by_email('user@admin.example.com')
# Add incremental custom claim without overwriting existing claims.
current_custom_claims = user.custom_claims
if current_custom_claims.get('admin'):
    # Add level.
    current_custom_claims['accessLevel'] = 10
    # Add custom claims for additional privileges.
    auth.set_custom_user_claims(user.uid, current_custom_claims)

ไป

user, err := client.GetUserByEmail(ctx, "user@admin.example.com")
if err != nil {
	log.Fatal(err)
}
// Add incremental custom claim without overwriting existing claims.
currentCustomClaims := user.CustomClaims
if currentCustomClaims == nil {
	currentCustomClaims = map[string]interface{}{}
}

if _, found := currentCustomClaims["admin"]; found {
	// Add level.
	currentCustomClaims["accessLevel"] = 10
	// Add custom claims for additional privileges.
	err := client.SetCustomUserClaims(ctx, user.UID, currentCustomClaims)
	if err != nil {
		log.Fatalf("error setting custom claims %v\n", err)
	}

}

ค#

UserRecord user = await FirebaseAuth.DefaultInstance
    .GetUserByEmailAsync("user@admin.example.com");
// Add incremental custom claims without overwriting the existing claims.
object isAdmin;
if (user.CustomClaims.TryGetValue("admin", out isAdmin) && (bool)isAdmin)
{
    var claims = new Dictionary<string, object>(user.CustomClaims);
    // Add level.
    claims["level"] = 10;
    // Add custom claims for additional privileges.
    await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(user.Uid, claims);
}