אימות אסימונים מזהים

אם אפליקציית הלקוח של Firebase מתקשרת עם שרת לקצה עורפי בהתאמה אישית, יכול להיות שתצטרכו לזהות את המשתמש שמחובר כרגע בשרת הזה. כדי לעשות זאת בצורה מאובטחת, אחרי כניסה מוצלחת, שולחים את אסימון המזהה של המשתמש לשרת באמצעות HTTPS. לאחר מכן, בשרת, מאמתים את השלמות והאותנטיות של אסימון המזהה ומאחזרים ממנו את uid. אפשר להשתמש ב-uid שמשודר בדרך הזו כדי לזהות באופן מאובטח את המשתמש המחובר הנוכחי בשרת.

לפני שמתחילים

כדי לאמת אסימוני מזהה באמצעות Firebase 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 לא תומכת בה באופן מקורי.

אימות אסימוני מזהה באמצעות ה-SDK של Firebase לאדמינים

ל-SDK של Firebase לאדמינים יש שיטה מובנית לאימות ולפענוח של אסימוני מזהה. אם פורמט אסימון המזהה שסופק נכון, התוקף שלו לא פג והוא חתום כראוי, השיטה מחזירה את אסימון המזהה שעבר פענוח. אפשר לקבל את הערך של 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;

כדי לאמת אסימון מזהה, צריך מזהה פרויקט. ה-SDK של Firebase Admin מנסה לקבל מזהה פרויקט באחת מהשיטות הבאות:

  • אם ה-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 של המשתמש או המכשיר התואם.