ยืนยันโทเค็นรหัส

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

ก่อนเริ่มต้น

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

ดึงข้อมูลโทเค็นระบุตัวตนในไคลเอ็นต์

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

iOS+

Objective-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();
            }
        }
    });

Unity

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
});

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

ยืนยันโทเค็นระบุตัวตนโดยใช้ Firebase Admin SDK

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

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

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']

Go

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)

C#

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

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

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

ยืนยันโทเค็นระบุตัวตนโดยใช้ไลบรารี JWT ของบุคคลที่สาม

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

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

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

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

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

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

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