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

หากแอปไคลเอ็นต์ 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 ของผู้ใช้หรืออุปกรณ์ที่เกี่ยวข้อง