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

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

قبل البدء

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

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

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

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

تتضمّن حزمة Firebase Admin SDK طريقة مدمجة للتحقّق من صحة علامات IDENTITY التشفير وفكّ تشفيرها. إذا كان الرمز المميّز للمعرّف المقدَّم بالتنسيق الصحيح، ولم ينتهِ صلاحيته، وتمت توقيعه بشكل صحيح، ستعرض الطريقة الرمز المميّز للمعرّف بعد فك تشفيره. يمكنك الحصول على 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
  });

جافا

// 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']

انتقال

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) باستخدام بيانات اعتماد حساب الخدمة، ستستخدم الحزمة الحقل 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 للمستخدم أو الجهاز المقابل.