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

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