إثبات ملكية الرموز المميّزة للهوية

إذا كان تطبيق العميل في 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 المميّز للويب (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 الحصول على رقم تعريف المشروع بإحدى الطرق التالية:

  • إذا تمت تهيئة حزمة SDK باستخدام خيار التطبيق projectId الصريح، تستخدِم حزمة SDK قيمة هذا الخيار.
  • إذا تمت تهيئة حزمة SDK باستخدام بيانات اعتماد حساب خدمة، تستخدِم حزمة SDK حقل project_id في عنصر JSON الخاص بحساب الخدمة.
  • إذا تم ضبط متغيّر البيئة GOOGLE_CLOUD_PROJECT، تستخدِم حزمة SDK قيمته كرقم تعريف المشروع. يتوفّر متغيّر البيئة هذا للرمز الذي يتم تشغيله على البنية الأساسية من Google، مثل App Engine وCompute Engine.

التحقّق من الرموز المميّزة للمعرّف باستخدام مكتبة JWT تابعة لجهة خارجية

إذا كان خادم الخلفية مكتوبًا بلغة غير متاح معها مدير SDK في Firebase، سيظل بإمكانك التحقّق من الرموز المميّزة للمعرّف. أولاً، ابحث عن مكتبة JWT تابعة لجهة خارجية للغتك. بعد ذلك، تحقَّق من العنوان والحمولة والتوقيع الخاصين بالرمز المميّز للمعرّف.

تأكَّد من أنّ عنوان الرمز المميّز للمعرّف يتوافق مع القيود التالية:

مطالبات عنوان الرمز المميّز للمعرّف
alg خوارزمية "RS256"
kid رقم تعريف المفتاح يجب أن يتطابق مع أحد المفاتيح العامة المدرَجة في https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com

تأكَّد من أنّ حمولة الرمز المميّز للمعرّف تتوافق مع القيود التالية:

مطالبات حمولة الرمز المميّز للمعرّف
exp وقت انتهاء الصلاحية يجب أن يكون في المستقبل. يتم قياس الوقت بالثواني منذ بدء حساب الفترة في نظام UNIX.
iat وقت الإصدار يجب أن يكون في الماضي. يتم قياس الوقت بالثواني منذ بدء حساب الفترة في نظام 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 للمستخدم أو الجهاز المقابل.