ยืนยัน ID Tokens

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

ก่อนจะเริ่ม

คุณต้องมีบัญชีบริการเพื่อยืนยันโทเค็น ID ด้วย Firebase Admin SDK ทำตาม คำแนะนำในการตั้งค่า Admin SDK เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเริ่มต้น Admin SDK ด้วยบัญชีบริการ

รับโทเค็น ID บนไคลเอนต์

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

iOS+

วัตถุประสงค์-C
FIRUser *currentUser = [FIRAuth auth].currentUser;
[currentUser getIDTokenForcingRefresh:YES
                           completion:^(NSString *_Nullable idToken,
                                        NSError *_Nullable error) {
          if (error) {
            // Handle error
            return;
          }

          // Send token to your backend via HTTPS
          // ...
}];
Swift
let currentUser = FIRAuth.auth()?.currentUser
currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
  if let error = error {
    // Handle error
    return;
  }

  // Send token to your backend via HTTPS
  // ...
}

Android

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
    .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
        public void onComplete(@NonNull Task<GetTokenResult> task) {
            if (task.isSuccessful()) {
                String idToken = task.getResult().getToken();
                // Send token to your backend via HTTPS
                // ...
            } else {
                // Handle error -> task.getException();
            }
        }
    });

ความสามัคคี

Firebase.Auth.FirebaseUser user = auth.CurrentUser;
user.TokenAsync(true).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("TokenAsync was canceled.");
   return;
  }

  if (task.IsFaulted) {
    Debug.LogError("TokenAsync encountered an error: " + task.Exception);
    return;
  }

  string idToken = task.Result;

  // Send token to your backend via HTTPS
  // ...
});

C++

firebase::auth::User user = auth->current_user();
if (user.is_valid()) {
  firebase::Future<std::string> idToken = user.GetToken(true);

  // Send token to your backend via HTTPS
  // ...
}

เว็บ

firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
  // Send token to your backend via HTTPS
  // ...
}).catch(function(error) {
  // Handle error
});

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

ตรวจสอบโทเค็น ID โดยใช้ Firebase Admin SDK

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

ทำตาม คำแนะนำในการตั้งค่า Admin SDK เพื่อเริ่มต้น Admin SDK ด้วยบัญชีบริการ จากนั้น ใช้ verifyIdToken() เพื่อตรวจสอบโทเค็น ID:

Node.js

// idToken comes from the client app
getAuth()
  .verifyIdToken(idToken)
  .then((decodedToken) => {
    const uid = decodedToken.uid;
    // ...
  })
  .catch((error) => {
    // Handle error
  });

Java

// idToken comes from the client app (shown above)
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(idToken);
String uid = decodedToken.getUid();

Python

# id_token comes from the client app (shown above)

decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']

ไป

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

token, err := client.VerifyIDToken(ctx, idToken)
if err != nil {
	log.Fatalf("error verifying ID token: %v\n", err)
}

log.Printf("Verified ID token: %v\n", token)

ค#

FirebaseToken decodedToken = await FirebaseAuth.DefaultInstance
    .VerifyIdTokenAsync(idToken);
string uid = decodedToken.Uid;

การตรวจสอบโทเค็น ID ต้องใช้รหัสโปรเจ็กต์ Firebase Admin SDK พยายามรับรหัสโปรเจ็กต์โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้

  • หาก SDK เริ่มต้นด้วยตัวเลือกแอป projectId อย่างชัดเจน SDK จะใช้ค่าของตัวเลือกนั้น
  • หาก SDK เริ่มต้นด้วยข้อมูลประจำตัวของบัญชีบริการ SDK จะใช้ฟิลด์ project_id ของออบเจ็กต์ JSON ของบัญชีบริการ
  • หากมีการตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_CLOUD_PROJECT SDK จะใช้ค่าเป็นรหัสโปรเจ็กต์ ตัวแปรสภาพแวดล้อมนี้ใช้ได้กับโค้ดที่ทำงานบนโครงสร้างพื้นฐานของ Google เช่น App Engine และ Compute Engine

ตรวจสอบโทเค็น ID โดยใช้ไลบรารี JWT บุคคลที่สาม

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

ตรวจสอบว่าส่วนหัวของโทเค็น ID สอดคล้องกับข้อจำกัดต่อไปนี้:

ID Token Header การอ้างสิทธิ์
alg อัลกอริทึม "RS256"
kid รหัสคีย์ ต้องสอดคล้องกับคีย์สาธารณะรายการใดรายการหนึ่งที่ https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com

ตรวจสอบว่าเพย์โหลดของโทเค็น ID สอดคล้องกับข้อจำกัดต่อไปนี้:

ID Token Payload การอ้างสิทธิ์
exp เวลาหมดอายุ ต้องเป็นในอนาคต เวลามีหน่วยเป็นวินาทีนับตั้งแต่ยุค UNIX
iat ออกในเวลา ต้องเป็นอดีต เวลามีหน่วยเป็นวินาทีนับตั้งแต่ยุค UNIX
aud ผู้ชม ต้องเป็นรหัสโปรเจ็กต์ Firebase ซึ่งเป็นตัวระบุเฉพาะสำหรับโปรเจ็กต์ Firebase ซึ่งอยู่ใน URL ของคอนโซลของโปรเจ็กต์นั้น
iss ผู้ออก ต้องเป็น "https://securetoken.google.com/<projectId>" โดยที่ <projectId> เป็นรหัสโปรเจ็กต์เดียวกับที่ใช้สำหรับ aud ด้านบน
sub เรื่อง ต้องเป็นสตริงที่ไม่ว่างและต้องเป็น uid ของผู้ใช้หรืออุปกรณ์
auth_time เวลาตรวจสอบสิทธิ์ ต้องเป็นอดีต เวลาที่ผู้ใช้ตรวจสอบสิทธิ์

สุดท้าย ตรวจสอบให้แน่ใจว่าโทเค็น ID ได้รับการลงนามโดยคีย์ส่วนตัวที่สอดคล้องกับการอ้างสิทธิ์ย่อยของโท kid น หยิบกุญแจสาธารณะจาก https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com และใช้ไลบรารี JWT เพื่อยืนยันลายเซ็น ใช้ค่า max-age ในส่วนหัว Cache-Control ของการตอบกลับจากปลายทางนั้นเพื่อทราบว่าเมื่อใดควรรีเฟรชคีย์สาธารณะ

หากการตรวจสอบข้างต้นทั้งหมดสำเร็จ คุณสามารถใช้หัวเรื่อง ( sub ) ของโทเค็น ID เป็น uid ของผู้ใช้หรืออุปกรณ์ที่เกี่ยวข้อง