إثبات صحة الرموز المميّزة للمعرّفات

في حال اتصال تطبيق عميل Firebase بخادم خلفية مخصَّص، قد تحتاج إلى تحديد المستخدم المُسجِّل الدخول حاليًا على ذلك الخادم. ولإجراء ذلك بشكل آمن، بعد تسجيل الدخول بنجاح، أرسِل الرمز المميز لمعرّف المستخدم إلى خادمك باستخدام HTTPS. بعد ذلك، تحقَّق من صحة ومصداقية الرمز المميّز للمعرّف على الخادم واسترِدّ uid منه. يمكنك استخدام uid المنقولة بهذه الطريقة لتحديد هوية المستخدم المسجّل دخوله حاليًا على خادمك بشكل آمن.

قبل البدء

للتحقّق من الرموز المميّزة للتعريف باستخدام حزمة تطوير البرامج (SDK) لمشرف Firebase، يجب أن يكون لديك حساب خدمة. اتّبع تعليمات إعداد حزمة تطوير البرامج (SDK) للمشرف للحصول على مزيد من المعلومات عن كيفية إعداد "حزمة SDK للمشرف" باستخدام حساب خدمة.

استرداد رموز المعرفات للعملاء

عندما يسجِّل مستخدم أو جهاز الدخول بنجاح، ينشئ Firebase رمزًا مميزًا مقابلاً للمعرِّف يحدده بشكل فريد ويمنحه إمكانية الوصول إلى العديد من الموارد، مثل قاعدة بيانات Firebase في الوقت الفعلي و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 إلى الواجهة الخلفية والتحقّق من صحته باستخدام "حزمة SDK لمشرفي Firebase" أو استخدام مكتبة JWT تابعة لجهة خارجية إذا كان الخادم مكتوبًا بلغة لا يتيحها Firebase.

إثبات ملكية الرموز المميّزة للتعريف باستخدام حزمة تطوير البرامج (SDK) لمشرف Firebase

تتضمّن حزمة تطوير البرامج (SDK) لمشرف Firebase طريقة مضمّنة للتحقّق من الرموز المميّزة للمعرّفات وفك ترميزها. إذا كان الرمز المميّز للمعرّف الذي تم تقديمه يتضمّن التنسيق الصحيح ولم تنتهِ صلاحيته وتم توقيعه بشكل صحيح، تعرض الطريقة الرمز المميّز للمعرّف الذي تم فك ترميزه. يمكنك الحصول على uid الخاص بالمستخدم أو الجهاز من الرمز المميّز الذي تم فك ترميزه.

اتّبِع تعليمات إعداد حزمة تطوير البرامج (SDK) للمشرف لإعداد حزمة 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) باستخدام بيانات اعتماد حساب الخدمة، ستستخدم الحزمة الحقل 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 للمستخدم أو الجهاز المعني.