Catch up on highlights from Firebase at Google I/O 2023. Learn more

สร้างโทเค็นที่กำหนดเอง

Firebase ให้คุณควบคุมการตรวจสอบสิทธิ์ได้อย่างสมบูรณ์โดยอนุญาตให้คุณตรวจสอบผู้ใช้หรืออุปกรณ์โดยใช้โทเค็นเว็บ JSON ที่ปลอดภัย (JWT) คุณสร้างโทเค็นเหล่านี้บนเซิร์ฟเวอร์ของคุณ ส่งกลับไปยังอุปกรณ์ไคลเอ็นต์ จากนั้นใช้โทเค็นเพื่อตรวจสอบสิทธิ์ผ่านเมธอด signInWithCustomToken()

คุณต้องสร้างจุดสิ้นสุดของเซิร์ฟเวอร์ที่ยอมรับข้อมูลรับรองการลงชื่อเข้าใช้ เช่น ชื่อผู้ใช้และรหัสผ่าน และหากข้อมูลรับรองถูกต้อง ให้ส่งคืน JWT ที่กำหนดเอง JWT แบบกำหนดเองที่ส่งคืนจากเซิร์ฟเวอร์ของคุณสามารถใช้โดยอุปกรณ์ไคลเอนต์เพื่อตรวจสอบสิทธิ์กับ Firebase ( iOS+ , Android , เว็บ ) เมื่อตรวจสอบสิทธิ์แล้ว ข้อมูลระบุตัวตนนี้จะถูกใช้เมื่อเข้าถึงบริการ Firebase อื่นๆ เช่น Firebase Realtime Database และ Cloud Storage นอกจากนี้ เนื้อหาของ JWT จะมีอยู่ในวัตถุ auth ต้องใน กฎความปลอดภัยของฐานข้อมูลเรียลไทม์ และวัตถุ request.auth ใน กฎความปลอดภัยของพื้นที่เก็บข้อมูลบนคลาวด์

คุณสามารถสร้างโทเค็นที่กำหนดเองด้วย Firebase Admin SDK หรือใช้ไลบรารี JWT ของบุคคลที่สาม หากเซิร์ฟเวอร์ของคุณเขียนด้วยภาษาที่ Firebase ไม่รองรับ

ก่อนที่คุณจะเริ่มต้น

โทเค็นที่กำหนดเองคือ JWT ที่ลงนามโดยคีย์ส่วนตัวที่ใช้สำหรับการลงนามเป็นของบัญชีบริการของ Google มีหลายวิธีในการระบุบัญชีบริการ Google ที่ Firebase Admin SDK ควรใช้สำหรับการลงนามโทเค็นที่กำหนดเอง:

  • การใช้ไฟล์ JSON ของบัญชีบริการ -- วิธีนี้สามารถใช้ได้ในทุกสภาพแวดล้อม แต่คุณต้องรวมไฟล์ JSON ของบัญชีบริการพร้อมกับโค้ดของคุณ ต้องใช้ความระมัดระวังเป็นพิเศษเพื่อให้แน่ใจว่าไฟล์ JSON ของบัญชีบริการจะไม่เปิดเผยต่อบุคคลภายนอก
  • การให้ Admin SDK ค้นพบบัญชีบริการ -- วิธีนี้สามารถใช้ได้ในสภาพแวดล้อมที่จัดการโดย Google เช่น Google Cloud Functions และ App Engine คุณอาจต้องกำหนดค่าการอนุญาตเพิ่มเติมผ่าน Google Cloud Console
  • การใช้รหัสบัญชีบริการ -- เมื่อใช้ในสภาพแวดล้อมที่จัดการโดย Google วิธีนี้จะลงนามโทเค็นโดยใช้คีย์ของบัญชีบริการที่ระบุ อย่างไรก็ตาม มันใช้บริการเว็บระยะไกล และคุณอาจต้องกำหนดค่าการอนุญาตเพิ่มเติมสำหรับบัญชีบริการนี้ผ่าน Google Cloud Console

ใช้ไฟล์ JSON ของบัญชีบริการ

ไฟล์ JSON ของบัญชีบริการมีข้อมูลทั้งหมดที่เกี่ยวข้องกับบัญชีบริการ (รวมถึงคีย์ส่วนตัว RSA) สามารถดาวน์โหลดได้จากคอนโซล Firebase ทำตาม คำแนะนำในการตั้งค่า Admin SDK สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีเริ่มต้น Admin SDK ด้วยไฟล์ JSON ของบัญชีบริการ

วิธีการเริ่มต้นนี้เหมาะสำหรับการปรับใช้ Admin SDK ที่หลากหลาย นอกจากนี้ยังช่วยให้ Admin SDK สร้างและลงนามโทเค็นที่กำหนดเองในเครื่องโดยไม่ต้องทำการเรียก API ระยะไกล ข้อเสียเปรียบหลักของแนวทางนี้คือคุณต้องจัดทำแพ็คเกจไฟล์ JSON ของบัญชีบริการพร้อมกับรหัสของคุณ โปรดทราบว่าคีย์ส่วนตัวในไฟล์ JSON ของบัญชีบริการเป็นข้อมูลที่ละเอียดอ่อน และต้องใช้ความระมัดระวังเป็นพิเศษเพื่อรักษาความลับ โดยเฉพาะอย่างยิ่ง ห้ามเพิ่มไฟล์ JSON ของบัญชีบริการในการควบคุมเวอร์ชันสาธารณะ

การให้ Admin SDK ค้นพบบัญชีบริการ

หากมีการปรับใช้รหัสของคุณในสภาพแวดล้อมที่จัดการโดย Google Admin SDK จะพยายามค้นหาวิธีโดยอัตโนมัติในการลงนามโทเค็นที่กำหนดเอง:

  • หากโค้ดของคุณถูกปรับใช้ในสภาพแวดล้อมมาตรฐานของ App Engine สำหรับ Java, Python หรือ Go, Admin SDK สามารถใช้ บริการ App Identity ที่มีอยู่ในสภาพแวดล้อมนั้นเพื่อลงนามโทเค็นที่กำหนดเอง บริการ App Identity ลงนามข้อมูลโดยใช้บัญชีบริการที่จัดเตรียมไว้สำหรับแอปของคุณโดย Google App Engine

  • หากรหัสของคุณใช้งานในสภาพแวดล้อมที่มีการจัดการอื่นๆ (เช่น Google Cloud Functions, Google Compute Engine) SDK ผู้ดูแลระบบ Firebase สามารถค้นหาสตริงรหัสบัญชีบริการจาก เซิร์ฟเวอร์ข้อมูลเมตา ในเครื่องได้โดยอัตโนมัติ รหัสบัญชีบริการที่ค้นพบจะใช้ร่วมกับบริการ IAM เพื่อลงนามโทเค็นจากระยะไกล

หากต้องการใช้วิธีการลงนามเหล่านี้ ให้เริ่มต้น SDK ด้วยข้อมูลประจำตัวเริ่มต้นของแอปพลิเคชัน Google และไม่ต้องระบุสตริง ID บัญชีบริการ:

โหนด js

initializeApp();

ชวา

FirebaseApp.initializeApp();

หลาม

default_app = firebase_admin.initialize_app()

ไป

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

ค#

FirebaseApp.Create();

หากต้องการทดสอบโค้ดเดียวกันในเครื่อง ให้ดาวน์โหลดไฟล์ JSON ของบัญชีบริการและตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_APPLICATION_CREDENTIALS ให้ชี้ไปที่ตัวแปรนั้น

หาก Firebase Admin SDK ต้องค้นหาสตริง ID บัญชีบริการ ก็จะพบเมื่อโค้ดของคุณสร้างโทเค็นที่กำหนดเองเป็นครั้งแรก ผลลัพธ์จะถูกแคชและใช้ซ้ำสำหรับการดำเนินการลงนามโทเค็นในภายหลัง รหัสบัญชีบริการที่ค้นพบโดยอัตโนมัติมักจะเป็นหนึ่งในบัญชีบริการเริ่มต้นที่ Google Cloud ให้บริการ:

เช่นเดียวกับรหัสบัญชีบริการที่ระบุอย่างชัดเจน รหัสบัญชีบริการที่ค้นพบอัตโนมัติต้องมีสิทธิ์ iam.serviceAccounts.signBlob เพื่อให้การสร้างโทเค็นแบบกำหนดเองทำงานได้ คุณอาจต้องใช้ส่วน IAM และผู้ดูแลระบบ ของ Google Cloud Console เพื่อให้สิทธิ์ที่จำเป็นแก่บัญชีบริการเริ่มต้น ดูส่วนการแก้ไขปัญหาด้านล่างสำหรับรายละเอียดเพิ่มเติม

ใช้รหัสบัญชีบริการ

เพื่อรักษาความสอดคล้องระหว่างส่วนต่างๆ ของแอปพลิเคชัน คุณสามารถระบุรหัสบัญชีบริการซึ่งจะใช้คีย์เพื่อลงนามโทเค็นเมื่อทำงานในสภาพแวดล้อมที่จัดการโดย Google ซึ่งจะทำให้นโยบาย IAM ง่ายขึ้นและปลอดภัยยิ่งขึ้น และไม่ต้องรวมไฟล์ JSON ของบัญชีบริการไว้ในโค้ดของคุณ

รหัสบัญชีบริการอยู่ใน Google Cloud Console หรือในช่อง client_email ของไฟล์ JSON ของบัญชีบริการที่ดาวน์โหลด รหัสบัญชีบริการคือที่อยู่อีเมลที่มีรูปแบบต่อไปนี้: <client-id>@<project-id>.iam.gserviceaccount.com พวกเขาระบุบัญชีบริการในโครงการ Firebase และ Google Cloud โดยไม่ซ้ำกัน

หากต้องการสร้างโทเค็นที่กำหนดเองโดยใช้ ID บัญชีบริการแยกต่างหาก ให้เริ่มต้น SDK ดังที่แสดงด้านล่าง:

โหนด js

initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});

ชวา

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);

หลาม

options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)

ไป

conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

ค#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});

รหัสบัญชีบริการไม่ใช่ข้อมูลที่ละเอียดอ่อน ดังนั้นการเปิดเผยจึงไม่สำคัญ อย่างไรก็ตาม หากต้องการลงนามโทเค็นที่กำหนดเองด้วยบัญชีบริการที่ระบุ Firebase Admin SDK จะต้องเรียกใช้บริการระยะไกล นอกจากนี้ คุณต้องตรวจสอบให้แน่ใจว่าบัญชีบริการที่ Admin SDK ใช้ในการโทรนี้ ซึ่งปกติแล้วคือ {project-name}@appspot.gserviceaccount.com ได้ รับอนุญาตจาก iam.serviceAccounts.signBlob ดูส่วนการแก้ไขปัญหาด้านล่างสำหรับรายละเอียดเพิ่มเติม

สร้างโทเค็นที่กำหนดเองโดยใช้ Firebase Admin SDK

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

โหนด js

const uid = 'some-uid';

getAuth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

ชวา

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

หลาม

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

ไป

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

ค#

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

คุณยังสามารถเลือกที่จะระบุการอ้างสิทธิ์เพิ่มเติมที่จะรวมไว้ในโทเค็นที่กำหนดเอง ตัวอย่างเช่น ด้านล่างนี้ มีการเพิ่มฟิลด์ premiumAccount ลงในโทเค็นแบบกำหนดเอง ซึ่งจะพร้อมใช้งานในวัตถุ auth / request.auth ในกฎความปลอดภัยของคุณ:

โหนด js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

getAuth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

ชวา

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

หลาม

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

ไป

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

ค#

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

ชื่อโทเค็นที่กำหนดเองที่สงวนไว้

ลงชื่อเข้าใช้โดยใช้โทเค็นที่กำหนดเองในไคลเอ็นต์

หลังจากที่คุณสร้างโทเค็นแบบกำหนดเองแล้ว คุณควรส่งไปยังแอปไคลเอนต์ของคุณ แอปไคลเอ็นต์ตรวจสอบความถูกต้องด้วยโทเค็นที่กำหนดเองโดยเรียก signInWithCustomToken() :

iOS+

วัตถุประสงค์-C
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
สวิฟต์
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
  // ...
}

แอนดรอยด์

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

ความสามัคคี

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.AuthResult result = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      result.User.DisplayName, result.User.UserId);
});

ภาษาซี++

firebase::Future<firebase::auth::AuthResult> result =
    auth->SignInWithCustomToken(custom_token);

Web version 8

firebase.auth().signInWithCustomToken(token)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

Web version 9

import { getAuth, signInWithCustomToken } from "firebase/auth";

const auth = getAuth();
signInWithCustomToken(auth, token)
  .then((userCredential) => {
    // Signed in
    const user = userCredential.user;
    // ...
  })
  .catch((error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
    // ...
  });

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

ในลักษณะเดียวกับวิธีการลงชื่อเข้าใช้อื่นๆ (เช่น signInWithEmailAndPassword() และ signInWithCredential() ) ออบ auth กต์การรับรองความถูกต้องใน กฎความปลอดภัยของฐานข้อมูลเรียลไทม์ และออบเจ็กต์ request.auth ใน กฎความปลอดภัยของ Cloud Storage จะถูกเติมด้วย uid ของผู้ใช้ . ในกรณีนี้ uid จะเป็นตัวที่คุณระบุเมื่อสร้างโทเค็นแบบกำหนดเอง

กฎฐานข้อมูล

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

กฎการจัดเก็บ

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}

หากโทเค็นที่กำหนดเองมีการอ้างสิทธิ์เพิ่มเติม สามารถอ้างอิงได้จาก auth.token (ฐานข้อมูลเรียลไทม์ของ Firebase) หรือ request.auth.token (ที่เก็บข้อมูลบนคลาวด์) ในกฎของคุณ:

กฎฐานข้อมูล

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

กฎการจัดเก็บ

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

สร้างโทเค็นแบบกำหนดเองโดยใช้ไลบรารี JWT ของบุคคลที่สาม

หากแบ็กเอนด์ของคุณเป็นภาษาที่ไม่มี Firebase Admin SDK อย่างเป็นทางการ คุณยังคงสร้างโทเค็นที่กำหนดเองได้ด้วยตนเอง ขั้นแรก ค้นหาไลบรารี JWT ของบุคคลที่สาม สำหรับภาษาของคุณ จากนั้นใช้ไลบรารี JWT นั้นเพื่อสร้าง JWT ซึ่งรวมถึงการอ้างสิทธิ์ต่อไปนี้:

การอ้างสิทธิ์โทเค็นแบบกำหนดเอง
alg อัลกอริทึม "RS256"
iss ผู้ออก ที่อยู่อีเมลบัญชีบริการของโครงการของคุณ
sub เรื่อง ที่อยู่อีเมลบัญชีบริการของโครงการของคุณ
aud ผู้ชม "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat ออก-ตามเวลา เวลาปัจจุบัน หน่วยเป็นวินาทีตั้งแต่ยุค UNIX
exp เวลาหมดอายุ เวลาเป็นวินาทีตั้งแต่ยุค UNIX ที่โทเค็นหมดอายุ อาจช้ากว่า iat สูงสุด 3600 วินาที
หมายเหตุ: สิ่งนี้จะควบคุมเวลาที่ โทเค็นที่กำหนด เองหมดอายุเท่านั้น แต่เมื่อคุณลงชื่อเข้าใช้ผู้ใช้โดยใช้ signInWithCustomToken() พวกเขาจะยังคงลงชื่อเข้าใช้ในอุปกรณ์จนกว่าเซสชันจะไม่ถูกต้องหรือผู้ใช้ออกจากระบบ
uid ตัวระบุเฉพาะของผู้ใช้ที่ลงชื่อเข้าใช้ต้องเป็นสตริงที่มีความยาวระหว่าง 1-128 อักขระ uid ที่สั้นกว่าให้ประสิทธิภาพที่ดีกว่า
claims (ไม่บังคับ) การอ้างสิทธิ์ที่กำหนดเองเพิ่มเติมเพื่อรวมไว้ในตัวแปร auth / request.auth ของกฎความปลอดภัย

ต่อไปนี้คือตัวอย่างการใช้งานวิธีสร้างโทเค็นที่กำหนดเองในภาษาต่างๆ ที่ Firebase Admin SDK ไม่รองรับ:

พี.เอช.พี

ใช้ php-jwt :

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

ทับทิม

ใช้ ruby-jwt :

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

หลังจากที่คุณสร้างโทเค็นที่กำหนดเองแล้ว ให้ส่งโทเค็นไปยังแอปไคลเอ็นต์เพื่อใช้ตรวจสอบสิทธิ์กับ Firebase ดูตัวอย่างโค้ดด้านบนสำหรับวิธีการทำเช่นนี้

การแก้ไขปัญหา

ส่วนนี้สรุปปัญหาทั่วไปบางประการที่นักพัฒนาซอฟต์แวร์อาจพบเมื่อสร้างโทเค็นแบบกำหนดเอง และวิธีการแก้ไข

ไม่ได้เปิดใช้งาน IAM API

หากคุณกำลังระบุ ID บัญชีบริการสำหรับโทเค็นการเซ็นชื่อ คุณอาจได้รับข้อผิดพลาดที่คล้ายกับต่อไปนี้:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

Firebase Admin SDK ใช้ IAM API เพื่อลงนามโทเค็น ข้อผิดพลาดนี้ระบุว่า IAM API ไม่ได้เปิดใช้งานสำหรับโปรเจ็กต์ Firebase ของคุณ เปิดลิงก์ในข้อความแสดงข้อผิดพลาดในเว็บเบราว์เซอร์ แล้วคลิกปุ่ม "เปิดใช้งาน API" เพื่อเปิดใช้งานสำหรับโครงการของคุณ

บัญชีบริการไม่มีสิทธิ์ที่จำเป็น

หากบัญชีบริการที่ Firebase Admin SDK เรียกใช้เนื่องจากไม่มีสิทธิ์ iam.serviceAccounts.signBlob คุณอาจได้รับข้อความแสดงข้อผิดพลาดดังต่อไปนี้:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

วิธีที่ง่ายที่สุดในการแก้ปัญหานี้คือการมอบบทบาท IAM ของ "Service Account Token Creator" ให้กับบัญชีบริการที่เป็นปัญหา โดยปกติจะเป็น {project-name}@appspot.gserviceaccount.com :

  1. เปิดหน้า IAM และผู้ดูแลระบบ ใน Google Cloud Console
  2. เลือกโครงการของคุณและคลิก "ดำเนินการต่อ"
  3. คลิกไอคอนแก้ไขที่เกี่ยวข้องกับบัญชีบริการที่คุณต้องการอัปเดต
  4. คลิกที่ "เพิ่มบทบาทอื่น"
  5. พิมพ์ "Service Account Token Creator" ลงในตัวกรองการค้นหา และเลือกจากผลลัพธ์
  6. คลิก "บันทึก" เพื่อยืนยันการมอบบทบาท

โปรดดู เอกสาร IAM สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการนี้ หรือเรียนรู้วิธีอัปเดตบทบาทโดยใช้เครื่องมือบรรทัดคำสั่ง gcloud

ระบุบัญชีบริการไม่สำเร็จ

หากคุณได้รับข้อความแสดงข้อผิดพลาดที่คล้ายกับข้อความต่อไปนี้ แสดงว่า Firebase Admin SDK ไม่ได้เริ่มต้นอย่างถูกต้อง

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

หากคุณใช้ SDK เพื่อค้นหา ID บัญชีบริการโดยอัตโนมัติ ตรวจสอบให้แน่ใจว่ารหัสนั้นใช้งานได้ในสภาพแวดล้อมของ Google ที่มีการจัดการด้วยเซิร์ฟเวอร์ข้อมูลเมตา มิฉะนั้น โปรดระบุไฟล์ JSON ของบัญชีบริการหรือรหัสบัญชีบริการเมื่อเริ่มต้น SDK