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

หากแอปไคลเอ็นต์ 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
});

เมื่อมีโทเค็นรหัสแล้ว คุณจะส่ง 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 เวลาหมดอายุ ต้องเป็นวันที่ในอนาคต เวลาจะวัดเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX
iat เวลาที่ออก ต้องเป็นวันที่ในอดีต เวลาจะวัดเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX
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 ของผู้ใช้หรืออุปกรณ์ที่เกี่ยวข้องได้