المصادقة مع Firebase من خلال رقم هاتف باستخدام JavaScript

يمكنك استخدام مصادقة Firebase لتسجيل دخول المستخدم عن طريق إرسال رسالة قصيرة SMS إلى هاتف المستخدم. يسجِّل المستخدم الدخول باستخدام رمز يُستخدم لمرة واحدة ضمن الرسالة القصيرة SMS.

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

قبل البدء

انسخ مقتطف الإعداد من وحدة تحكّم Firebase إلى مشروعك على النحو الموضّح في المقالة إضافة Firebase إلى مشروع JavaScript إذا لم يسبق لك إجراء ذلك.

المخاوف المرتبطة بالأمان

تكون المصادقة باستخدام رقم الهاتف فقط، على الرغم من كونها ملائمة، أقل أمانًا من الطرق الأخرى المتاحة، نظرًا لأنه يمكن نقل حيازة رقم الهاتف بسهولة بين المستخدمين. وعلى الأجهزة التي تحتوي على عدة ملفات شخصية للمستخدمين، يمكن لأي مستخدم يمكنه تلقّي الرسائل القصيرة تسجيل الدخول إلى الحساب باستخدام رقم هاتف الجهاز.

إذا كنت تستخدم نظام تسجيل الدخول عبر رقم الهاتف في تطبيقك، عليك توفيره إلى جانب طرق أكثر أمانًا لتسجيل الدخول، وإعلام المستخدمين بالمقايضات الأمنية لتسجيل الدخول باستخدام رقم الهاتف.

تفعيل ميزة "تسجيل الدخول باستخدام رقم الهاتف" لمشروع Firebase

لتسجيل دخول المستخدمين عبر الرسائل القصيرة SMS، يجب أولاً تفعيل طريقة تسجيل الدخول باستخدام رقم الهاتف لمشروع Firebase:

  1. في وحدة تحكُّم Firebase، افتح قسم المصادقة.
  2. في صفحة طريقة تسجيل الدخول، فعِّل طريقة تسجيل الدخول رقم الهاتف.
  3. في الصفحة نفسها، إذا لم يكن النطاق الذي سيستضيف تطبيقك مُدرَجًا في قسم نطاقات إعادة توجيه OAuth، أضِف نطاقك.

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

إعداد أداة التحقّق من reCAPTCHA

قبل أن تتمكّن من تسجيل دخول المستخدمين باستخدام أرقام هواتفهم، عليك إعداد أداة التحقّق من reCAPTCHA من Firebase. يستخدم Firebase اختبار reCAPTCHA لمنع إساءة الاستخدام، مثلاً عن طريق ضمان أنّ طلب إثبات ملكية رقم الهاتف وارد من أحد النطاقات المسموح بها في تطبيقك.

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

يتيح الكائن RecaptchaVerifier استخدام reCAPTCHA غير المرئي، ويتيح غالبًا التحقّق من هوية المستخدم بدون الحاجة إلى أيّ إجراء، بالإضافة إلى تطبيق reCAPTCHA المصغّر الذي يتطلّب دائمًا تفاعل المستخدم لإكماله بنجاح.

يمكن ترجمة اختبار reCAPTCHA الأساسي المعروض وفقًا لما يفضّله المستخدم من خلال تعديل رمز اللغة على مثيل المصادقة قبل عرض reCAPTCHA. ستنطبق الأقلمة المذكورة أعلاه أيضًا على رسالة SMS المرسلة إلى المستخدم، والتي تحتوي على رمز التحقق.

واجهة برمجة التطبيقات Web modular API

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

واجهة برمجة التطبيقات لمساحة الاسم على الويب

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

استخدام خدمة reCAPTCHA غير المرئية

لاستخدام reCAPTCHA غير مرئي، أنشِئ كائن RecaptchaVerifier مع ضبط المعلَمة size على invisible، مع تحديد معرّف الزر الذي يرسل نموذج تسجيل الدخول. على سبيل المثال:

واجهة برمجة التطبيقات Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

استخدام تطبيق reCAPTCHA المصغّر

لاستخدام التطبيق المصغّر المرئي لخدمة reCAPTCHA، أنشِئ عنصرًا على صفحتك لتضمين الأداة، ثم أنشئ كائن RecaptchaVerifier مع تحديد معرّف الحاوية عند إجراء ذلك. على سبيل المثال:

واجهة برمجة التطبيقات Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

اختياري: تحديد مَعلمات reCAPTCHA

يمكنك اختياريًا ضبط دوال رد الاتصال في كائن RecaptchaVerifier الذي يتم استدعاؤه عندما يحل المستخدم اختبار ReCAPTCHA أو تنتهي صلاحية reCAPTCHA قبل أن يرسل المستخدم النموذج:

واجهة برمجة التطبيقات Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

اختياري: عرض reCAPTCHA مسبقًا

إذا أردت عرض reCAPTCHA مسبقًا قبل إرسال طلب تسجيل الدخول، يمكنك الاتصال بالرقم render:

واجهة برمجة التطبيقات Web modular API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

بعد حلّ render، ستحصل على رقم تعريف التطبيق المصغّر الخاص بـ reCAPTCHA، والذي يمكنك استخدامه لإجراء اتصالات بواجهة برمجة تطبيقات reCAPTCHA:

واجهة برمجة التطبيقات Web modular API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

واجهة برمجة التطبيقات لمساحة الاسم على الويب

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

إرسال رمز تحقُّق إلى هاتف المستخدم

لبدء تسجيل الدخول إلى رقم الهاتف، قدِّم للمستخدم واجهة تطلب منه تقديم رقم هاتفه، ثم اتصِل بالرقم signInWithPhoneNumber لتطلب من Firebase إرسال رمز مصادقة إلى هاتف المستخدم من خلال رسالة SMS:

  1. الحصول على رقم هاتف المستخدم

    تختلف المتطلبات القانونية، ولكن وفقًا لأفضل الممارسات ولتحديد التوقعات للمستخدمين، يجب إبلاغهم بأنّه في حال تسجيل الدخول عبر الهاتف، قد يتلقّون رسالة قصيرة (SMS) لإثبات الملكية وسيتم تطبيق الأسعار العادية.

  2. يمكنك الاتصال بالرقم signInWithPhoneNumber، مع تمرير رقم هاتف المستخدم وRecaptchaVerifier الذي أنشأته سابقًا إليه.

    واجهة برمجة التطبيقات Web modular API

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    واجهة برمجة التطبيقات لمساحة الاسم على الويب

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    إذا أدّت signInWithPhoneNumber إلى حدوث خطأ، أعِد ضبط reCAPTCHA حتى يتمكن المستخدم من إعادة المحاولة:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

تُصدر الطريقة signInWithPhoneNumber تحدي reCAPTCHA للمستخدم، وإذا اجتاز المستخدم الاختبار، تطلب من مصادقة Firebase إرسال رسالة SMS تحتوي على رمز التحقق إلى هاتف المستخدم.

سجّل دخول المستخدم باستخدام رمز التحقق

بعد نجاح الاتصال برقم signInWithPhoneNumber، اطلب من المستخدم كتابة رمز التحقق الذي تلقّاه عبر رسالة SMS. بعد ذلك، سجِّل دخول المستخدم من خلال تمرير الرمز إلى الطريقة confirm للكائن ConfirmationResult الذي تم تمريره إلى معالج التنفيذ signInWithPhoneNumber (أي حظر then). على سبيل المثال:

واجهة برمجة التطبيقات Web modular API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

إذا تم الاتصال برقم confirm بنجاح، يعني ذلك أنّ المستخدم سجّل دخوله بنجاح.

الحصول على الكائن المتوسط AuthCredential

إذا كنت بحاجة إلى الحصول على عنصر AuthCredential لحساب المستخدم، يُرجى تمرير رمز التحقّق من نتيجة التأكيد ورمز التحقق إلى PhoneAuthProvider.credential بدلاً من النقر على confirm:

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

وبعد ذلك، يمكنك تسجيل دخول المستخدم باستخدام بيانات الاعتماد:

firebase.auth().signInWithCredential(credential);

الاختبار باستخدام أرقام هواتف خيالية

ويمكنك إعداد أرقام هواتف خيالية للتطوير من خلال وحدة تحكُّم Firebase. يوفر الاختبار باستخدام أرقام الهاتف الخيالية المزايا التالية:

  • يمكنك اختبار مصادقة رقم الهاتف بدون استهلاك حصة الاستخدام.
  • اختبار مصادقة رقم الهاتف بدون إرسال رسالة SMS فعلية.
  • يمكنك إجراء اختبارات متتالية باستخدام رقم الهاتف نفسه بدون تقييد. ويقلّل ذلك من خطر الرفض أثناء عملية مراجعة متجر التطبيقات إذا تصادف أن يستخدم المُراجع رقم الهاتف نفسه للاختبار.
  • يمكنك الاختبار بسهولة في بيئات التطوير بدون أي جهد إضافي، مثل القدرة على التطوير باستخدام محاكي iOS أو محاكي Android بدون "خدمات Google Play".
  • يمكنك كتابة اختبارات الدمج بدون حظر عمليات فحص الأمان التي يتم تطبيقها عادةً على أرقام هواتف حقيقية في بيئة إنتاج.

يجب أن تستوفي أرقام الهواتف الخيالية المتطلبات التالية:

  1. احرص على استخدام أرقام هواتف خيالية بالفعل، وغير موجودة. لا تسمح لك مصادقة Firebase بضبط أرقام الهواتف الحالية التي يستخدمها مستخدمون حقيقيون كأرقام اختبار. أحد الخيارات المتاحة هو استخدام 555 رقمًا يبدأ ببادئة كأرقام هواتف تجريبية في الولايات المتحدة، مثلاً: +1 650-555-3434
  2. يجب أن تكون أرقام الهواتف منسَّقة بشكل صحيح لتناسب طولها وغيرها من القيود. سيظلان يخضعان لعملية التحقق نفسها مثل رقم هاتف المستخدم الحقيقي.
  3. يمكنك إضافة ما يصل إلى 10 أرقام هواتف لعملية التطوير.
  4. استخدِم أرقام هواتف أو رموزًا اختبارية يصعب تخمينها وتغييرها بشكل متكرّر.

إنشاء أرقام هواتف ورموز تحقُّق وهمية

  1. في وحدة تحكُّم Firebase، افتح قسم المصادقة.
  2. في علامة التبويب طريقة تسجيل الدخول، فعِّل مقدِّم خدمة الهاتف إذا لم يسبق لك إجراء ذلك.
  3. افتح قائمة أكورديون أرقام الهاتف للاختبار.
  4. أدخِل رقم الهاتف الذي تريد اختباره، على سبيل المثال: +1 650-555-3434.
  5. أدخِل رمز التحقّق المكوَّن من 6 أرقام لهذا الرقم تحديدًا، على سبيل المثال: 654321.
  6. أضِف الرقم. وإذا لزم الأمر، يمكنك حذف رقم الهاتف ورمزه من خلال تمرير مؤشر الماوس فوق الصف المقابل والنقر على رمز المهملات.

الاختبار اليدوي

يمكنك البدء مباشرةً في استخدام رقم هاتف وهمي في تطبيقك. ويتيح لك ذلك إجراء اختبار يدوي أثناء مراحل التطوير بدون التعرُّض إلى مشاكل متعلّقة بالحصة أو التقييد. يمكنك أيضًا إجراء الاختبارات مباشرةً من خلال محاكي iOS أو محاكي Android بدون تثبيت "خدمات Google Play".

عندما تقدم رقم الهاتف الوهمي وترسل رمز التحقق، لن يتم إرسال رسالة قصيرة SMS فعلية. بدلاً من ذلك، تحتاج إلى تقديم رمز التحقق الذي تم إعداده مسبقًا لإكمال عملية تسجيل الدخول.

عند اكتمال تسجيل الدخول، يتم إنشاء مستخدم Firebase برقم الهاتف هذا. يمتاز المستخدم بالسلوك والخصائص نفسها التي يستخدمها مستخدم رقم هاتف حقيقي، ويمكنه الوصول إلى قاعدة بيانات الوقت الفعلي/Cloud Firestore والخدمات الأخرى بالطريقة نفسها. يكون للرمز المميّز لرقم التعريف الذي تم إنشاؤه أثناء هذه العملية التوقيع نفسه لمستخدم رقم هاتف حقيقي.

ويمكنك أيضًا تحديد دور تجريبي من خلال المطالبات المخصّصة لهؤلاء المستخدمين لتمييزهم كمستخدمين مزيّفين إذا كنت تريد فرض قيود إضافية على إمكانية الوصول.

اختبار الدمج

بالإضافة إلى الاختبار اليدوي، توفّر مصادقة Firebase واجهات برمجة تطبيقات للمساعدة في كتابة اختبارات الدمج لاختبار مصادقة الهاتف. وتوقِف واجهات برمجة التطبيقات هذه التحقّق من التطبيقات من خلال إيقاف متطلبات reCAPTCHA في الويب والإشعارات الفورية الصامتة في نظام التشغيل iOS. وهذا يجعل اختبار الأتمتة ممكنًا في هذه التدفقات وأسهل في التنفيذ. بالإضافة إلى ذلك، تساعد في توفير إمكانية اختبار خطوات إثبات الملكية الفوري على Android.

على الويب، يجب ضبط السمة appVerificationDisabledForTesting على true قبل عرض السمة firebase.auth.RecaptchaVerifier. ويؤدي هذا إلى حل اختبار reCAPTCHA تلقائيًا، ما يسمح لك بتمرير رقم الهاتف بدون حله يدويًا. يُرجى العِلم أنّه على الرغم من إيقاف reCAPTCHA، لن تكتمل عملية تسجيل الدخول باستخدام رقم هاتف غير حقيقي. لا يمكن استخدام سوى أرقام الهواتف الخيالية فقط مع واجهة برمجة التطبيقات هذه.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

تختلف سلوك أدوات التحقّق من تطبيقات reCAPTCHA المرئية وغير المرئية عند إيقاف التحقّق من التطبيق:

  • اختبار reCAPTCHA المرئي: عند عرض اختبار reCAPTCHA المرئي من خلال appVerifier.render()، يتم حلّ المشكلة تلقائيًا بعد جزء من الثانية. يعادل ذلك نقر المستخدم على reCAPTCHA فور العرض. ستنتهي صلاحية استجابة reCAPTCHA بعد بعض الوقت ثم يتم حلّها تلقائيًا مرة أخرى.
  • غير مرئي من reCAPTCHA: لا يتم حل reCAPTCHA غير المرئية تلقائيًا عند العرض، بل يتم حل ذلك تلقائيًا عند طلب appVerifier.verify()الاستدعاء أو عند النقر على زر الارتساء في reCAPTCHA بعد جزء من التأخير من الثانية. وبالمثل، ستنتهي صلاحية الاستجابة بعد مرور بعض الوقت ولن يتم حلها تلقائيًا إلا بعد استدعاء appVerifier.verify() أو عند النقر على علامة ارتساء زر reCAPTCHA مرة أخرى.

وعندما يتم حل reCAPTCHA تجريبي، يتم تشغيل دالة معاودة الاتصال المقابلة كما هو متوقع مع الاستجابة الزائفة. إذا تم أيضًا تحديد معاودة الاتصال لانتهاء الصلاحية، سيتم تشغيلها عند انتهاء الصلاحية.

الخطوات اللاحقة

بعد تسجيل دخول المستخدم للمرة الأولى، يتم إنشاء حساب مستخدم جديد وربطه ببيانات الاعتماد، أي اسم المستخدم وكلمة المرور، أو رقم الهاتف، أو معلومات مقدم خدمة المصادقة. يتم تخزين هذا الحساب الجديد كجزء من مشروعك في Firebase، ويمكن استخدامه لتحديد مستخدم على مستوى كل تطبيق في مشروعك، بغض النظر عن كيفية تسجيل المستخدم للدخول.

  • الطريقة التي ننصح بها في تطبيقاتك لمعرفة حالة المصادقة للمستخدم هي ضبط مراقب على كائن Auth. يمكنك بعد ذلك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من كائن User. يُرجى الاطّلاع على إدارة المستخدمين.

  • في قاعدة بيانات Firebase في الوقت الفعلي وقواعد أمان Cloud Storage، يمكنك الحصول على رقم تعريف المستخدم الفريد للمستخدم الذي سجّل الدخول من المتغيّر auth واستخدامه للتحكّم في البيانات التي يمكن للمستخدم الوصول إليها.

يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام عدة موفِّري مصادقة من خلال ربط بيانات اعتماد موفِّر المصادقة بحساب مستخدم حالي.

لتسجيل خروج مستخدم، يمكنك الاتصال بالرقم signOut:

واجهة برمجة التطبيقات Web modular API

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

واجهة برمجة التطبيقات لمساحة الاسم على الويب

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});