Firebase ช่วยให้คุณควบคุมการตรวจสอบสิทธิ์ได้อย่างสมบูรณ์โดยให้คุณตรวจสอบสิทธิ์ผู้ใช้หรืออุปกรณ์โดยใช้โทเค็นเว็บ JSON (JWT) ที่ปลอดภัย คุณสร้างโทเค็นเหล่านี้ในเซิร์ฟเวอร์ ส่งกลับไปยังอุปกรณ์ไคลเอ็นต์ แล้วใช้โทเค็นดังกล่าวเพื่อตรวจสอบสิทธิ์ผ่านวิธีการ signInWithCustomToken()
หากต้องการดำเนินการดังกล่าว คุณต้องสร้างปลายทางเซิร์ฟเวอร์ที่ยอมรับข้อมูลเข้าสู่ระบบ เช่น ชื่อผู้ใช้และรหัสผ่าน และถ้าข้อมูลเข้าสู่ระบบถูกต้อง ระบบจะแสดง JWT ที่กำหนดเอง จากนั้นอุปกรณ์ไคลเอ็นต์จะใช้ JWT ที่กําหนดเองซึ่งส่งคืนจากเซิร์ฟเวอร์เพื่อตรวจสอบสิทธิ์กับ Firebase ได้ (iOS+, Android, เว็บ) เมื่อตรวจสอบสิทธิ์แล้ว ระบบจะใช้ข้อมูลประจำตัวนี้เมื่อเข้าถึงบริการอื่นๆ ของ Firebase เช่น Firebase Realtime Database และ Cloud Storage นอกจากนี้ เนื้อหาของ JWT จะอยู่ในออบเจ็กต์ auth
ใน Realtime Database Security Rules และออบเจ็กต์ request.auth
ใน Cloud Storage Security Rules
คุณสามารถสร้างโทเค็นที่กําหนดเองด้วย Firebase Admin SDK หรือจะใช้ไลบรารี JWT ของบุคคลที่สามก็ได้หากเซิร์ฟเวอร์เขียนด้วยภาษาที่ Firebase ไม่รองรับโดยค่าเริ่มต้น
ก่อนเริ่มต้น
โทเค็นที่กำหนดเองคือ JWT ที่ลงชื่อซึ่งคีย์ส่วนตัวที่ใช้ลงชื่อเป็นของบัญชีบริการของ Google การกำหนดบัญชีบริการ Google ที่ Firebase Admin SDK ควรใช้เพื่อลงนามโทเค็นที่กำหนดเองทำได้หลายวิธี ดังนี้
- การใช้ไฟล์ JSON ของบัญชีบริการ -- ใช้วิธีการนี้ได้ในทุกสภาพแวดล้อม แต่คุณจะต้องแพ็กเกจไฟล์ JSON ของบัญชีบริการพร้อมกับโค้ด โปรดใช้ความระมัดระวังเป็นพิเศษเพื่อให้แน่ใจว่าไฟล์ JSON ของบัญชีบริการจะไม่เปิดเผยต่อบุคคลภายนอก
- การอนุญาตให้ Admin SDK ค้นพบบัญชีบริการ -- วิธีการนี้ใช้ได้ในสภาพแวดล้อมที่ Google เป็นผู้จัดการ เช่น Google Cloud Functions และ App Engine คุณอาจต้องกำหนดค่าสิทธิ์เพิ่มเติมบางอย่างผ่านคอนโซล Google Cloud
- การใช้รหัสบัญชีบริการ -- เมื่อใช้ในสภาพแวดล้อมที่ Google จัดการ วิธีการนี้จะลงนามในโทเค็นโดยใช้คีย์ของบัญชีบริการที่ระบุ แต่จะใช้เว็บเซอร์วิสระยะไกล และคุณอาจต้องกำหนดค่าสิทธิ์เพิ่มเติมสำหรับบัญชีบริการนี้ผ่านคอนโซล Google Cloud
การใช้ไฟล์ 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 จะใช้บริการระบุตัวตนของแอปที่มีอยู่ในสภาพแวดล้อมดังกล่าวเพื่อลงนามโทเค็นที่กําหนดเองได้ บริการระบุตัวตนของแอปจะเซ็นสัญญาข้อมูลโดยใช้บัญชีบริการที่ Google App Engine จัดสรรไว้ให้แอปของคุณ
หากมีการทําให้โค้ดใช้งานได้ในสภาพแวดล้อมที่มีการจัดการอื่นๆ (เช่น Google Cloud Functions, Google Compute Engine) Firebase Admin SDK จะค้นหาสตริงรหัสบัญชีบริการจากเซิร์ฟเวอร์ข้อมูลเมตาในเครื่องโดยอัตโนมัติ จากนั้นระบบจะใช้รหัสบัญชีบริการที่ค้นพบร่วมกับบริการ IAM เพื่อลงนามในโทเค็นจากระยะไกล
หากต้องการใช้วิธีการลงนามเหล่านี้ ให้เริ่มต้น SDK ด้วยข้อมูลเข้าสู่ระบบเริ่มต้นของ Google Appication และอย่าระบุสตริงรหัสบัญชีบริการ
Node.js
initializeApp();
Java
FirebaseApp.initializeApp();
Python
default_app = firebase_admin.initialize_app()
Go
app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
log.Fatalf("error initializing app: %v\n", err)
}
C#
FirebaseApp.Create();
หากต้องการทดสอบโค้ดเดียวกันในเครื่อง ให้ดาวน์โหลดไฟล์ JSON ของบัญชีบริการและตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_APPLICATION_CREDENTIALS
ให้ชี้ไปยังไฟล์ดังกล่าว
หาก Firebase Admin SDK ต้องค้นหาสตริงรหัสบัญชีบริการ การดำเนินการนี้จะดำเนินการเมื่อโค้ดของคุณสร้างโทเค็นที่กำหนดเองเป็นครั้งแรก ผลลัพธ์จะได้รับการแคชและนำมาใช้ซ้ำสำหรับการดำเนินการลงนามโทเค็นครั้งต่อๆ ไป รหัสบัญชีบริการที่ค้นพบอัตโนมัติมักจะเป็นหนึ่งในบัญชีบริการเริ่มต้นที่ Google Cloud ระบุไว้ ดังนี้
เช่นเดียวกับรหัสบัญชีบริการที่ระบุไว้อย่างชัดเจน รหัสบัญชีบริการที่ค้นพบโดยอัตโนมัติต้องมีสิทธิ์ iam.serviceAccounts.signBlob
เพื่อให้การสร้างโทเค็นที่กำหนดเองทำงานได้ คุณอาจต้องใช้ส่วน IAM และผู้ดูแลระบบของคอนโซล Google Cloud เพื่อมอบสิทธิ์ที่จําเป็นแก่บัญชีบริการเริ่มต้น โปรดดูรายละเอียดเพิ่มเติมที่ส่วนการแก้ปัญหาด้านล่าง
การใช้รหัสบัญชีบริการ
คุณสามารถระบุรหัสบัญชีบริการที่จะใช้คีย์เพื่อลงนามในโทเค็นเมื่อทํางานในสภาพแวดล้อมที่ Google จัดการ เพื่อให้แอปพลิเคชันส่วนต่างๆ ทำงานสอดคล้องกัน วิธีนี้ช่วยให้นโยบาย IAM ง่ายและปลอดภัยยิ่งขึ้น และไม่ต้องใส่ไฟล์ JSON ของบัญชีบริการไว้ในโค้ด
รหัสบัญชีบริการจะอยู่ในคอนโซล Google Cloud หรือในช่อง client_email
ของไฟล์ JSON ของบัญชีบริการที่ดาวน์โหลด
รหัสบัญชีบริการคืออีเมลในรูปแบบต่อไปนี้: <client-id>@<project-id>.iam.gserviceaccount.com
ซึ่งจะระบุบัญชีบริการในโปรเจ็กต์ Firebase และ Google Cloud โดยไม่ซ้ำกัน
หากต้องการสร้างโทเค็นที่กำหนดเองโดยใช้รหัสบัญชีบริการแยกต่างหาก ให้เริ่มต้น SDK ดังที่แสดงด้านล่าง
Node.js
initializeApp({
serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
Java
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
.build();
FirebaseApp.initializeApp(options);
Python
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
Go
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)
}
C#
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
ซึ่งอาจเป็นสตริงใดก็ได้ แต่ควรระบุผู้ใช้หรืออุปกรณ์ที่คุณกำลังตรวจสอบสิทธิ์ให้ระบุตัวตนได้โดยไม่ซ้ำกัน โทเค็นเหล่านี้จะหมดอายุหลังจากผ่านไป 1 ชั่วโมง
Node.js
const uid = 'some-uid';
getAuth()
.createCustomToken(uid)
.then((customToken) => {
// Send token back to client
})
.catch((error) => {
console.log('Error creating custom token:', error);
});
Java
String uid = "some-uid";
String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client
Python
uid = 'some-uid'
custom_token = auth.create_custom_token(uid)
Go
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)
C#
var uid = "some-uid";
string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client
นอกจากนี้ คุณยังระบุการอ้างสิทธิ์เพิ่มเติมที่จะรวมไว้ในโทเค็นที่กําหนดเองได้ด้วย ตัวอย่างเช่น ด้านล่างได้มีการเพิ่มช่อง premiumAccount
ลงในโทเค็นที่กำหนดเอง ซึ่งจะพร้อมใช้งานในออบเจ็กต์ auth
/ request.auth
ในกฎความปลอดภัยของคุณ
Node.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);
});
Java
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
Python
uid = 'some-uid'
additional_claims = {
'premiumAccount': True
}
custom_token = auth.create_custom_token(uid, additional_claims)
Go
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)
C#
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 ขึ้นไป
Objective-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Swift
Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in
// ...
}
Android
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);
}
}
});
Unity
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);
});
C++
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
Web
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Web
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
ที่รวมอยู่ในโทเค็นที่กำหนดเอง หากบัญชีดังกล่าวไม่เคยมีมาก่อน ระบบจะสร้างระเบียนสำหรับผู้ใช้รายนั้น
ระบบจะป้อนข้อมูล uid
ของผู้ใช้ลงในออบเจ็กต์ auth
ใน Realtime Database Security Rules และออบเจ็กต์ request.auth
ใน Cloud Storage Security Rules ในลักษณะเดียวกับวิธีการลงชื่อเข้าใช้อื่นๆ (เช่น signInWithEmailAndPassword()
และ signInWithCredential()
) ในกรณีนี้ 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 Realtime Database) หรือ request.auth.token
(Cloud Storage) ในกฎของคุณ
กฎฐานข้อมูล
{
"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 ของบุคคลที่สาม
หากแบ็กเอนด์เป็นภาษาที่ไม่มี SDK ผู้ดูแลระบบ Firebase อย่างเป็นทางการ คุณยังคงสร้างโทเค็นที่กำหนดเองได้ด้วยตนเอง ขั้นแรก ให้ค้นหาไลบรารี JWT ของบุคคลที่สามสำหรับภาษาของคุณ จากนั้นใช้ไลบรารี JWT ดังกล่าวเพื่อสร้าง JWT ซึ่งมีข้อมูลอ้างสิทธิ์ต่อไปนี้
การอ้างสิทธิ์โทเค็นที่กำหนดเอง | ||
---|---|---|
alg |
อัลกอริทึม | "RS256" |
iss |
ผู้ออก | อีเมลบัญชีบริการของโปรเจ็กต์ |
sub |
เรื่อง | อีเมลบัญชีบริการของโปรเจ็กต์ |
aud |
กลุ่มเป้าหมาย | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
เวลาที่ออก | เวลาปัจจุบันเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX |
exp |
เวลาหมดอายุ |
เวลาเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX ที่โทเค็นจะหมดอายุ โดยช้ากว่า iat ได้สูงสุด 3,600 วินาที
หมายเหตุ: การตั้งค่านี้จะควบคุมเวลาที่โทเค็นที่กำหนดเองหมดอายุเท่านั้น แต่หลังจากที่คุณลงชื่อเข้าใช้ผู้ใช้โดยใช้ signInWithCustomToken() ผู้ใช้จะยังคงลงชื่อเข้าใช้อุปกรณ์จนกว่าเซสชันจะใช้งานไม่ได้หรือผู้ใช้ออกจากระบบ
|
uid |
ตัวระบุที่ไม่ซ้ำกันของผู้ใช้ที่ลงชื่อเข้าใช้ต้องเป็นสตริงที่มีความยาวระหว่าง 1-128 อักขระ uid ที่สั้นกว่าให้ประสิทธิภาพที่ดีกว่า
|
|
claims (ไม่บังคับ) |
การอ้างสิทธิ์ที่กำหนดเองที่ไม่บังคับซึ่งรวมไว้ในตัวแปร auth / request.auth ของกฎความปลอดภัย
|
ตัวอย่างการใช้งานในการสร้างโทเค็นที่กําหนดเองในภาษาต่างๆ ที่ Firebase Admin SDK ไม่รองรับมีดังนี้
PHP
วิธีใช้ 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
วิธีใช้ 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
หากคุณระบุรหัสบัญชีบริการสำหรับการลงนามในโทเค็น คุณอาจได้รับข้อผิดพลาดที่คล้ายกับข้อความต่อไปนี้
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 "ผู้สร้างโทเค็นบัญชีบริการ" แก่บัญชีบริการที่เป็นปัญหา ซึ่งโดยปกติแล้ว{project-name}@appspot.gserviceaccount.com
- เปิดหน้า IAM และผู้ดูแลระบบ ในคอนโซล Google Cloud
- เลือกโปรเจ็กต์แล้วคลิก "ต่อไป"
- คลิกไอคอนแก้ไขของบัญชีบริการที่ต้องการอัปเดต
- คลิกที่ "เพิ่มบทบาทอื่น"
- พิมพ์ "ผู้สร้างโทเค็นบัญชีบริการ" ลงในตัวกรองการค้นหา แล้วเลือกจากผลการค้นหา
- คลิก "บันทึก" เพื่อยืนยันการให้บทบาท
โปรดดูรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการนี้ในเอกสารประกอบ 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 เพื่อค้นหารหัสบัญชีบริการโดยอัตโนมัติ ให้ตรวจสอบว่าได้ติดตั้งใช้งานโค้ดในสภาพแวดล้อม Google ที่มีการจัดการซึ่งมีเซิร์ฟเวอร์ข้อมูลเมตา หรืออย่าลืมระบุไฟล์ JSON ของบัญชีบริการหรือรหัสบัญชีบริการเมื่อเริ่มต้น SDK