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

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

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

قبل ان تبدأ

إذا لم تكن قد قمت بذلك بالفعل، فانسخ مقتطف التهيئة من وحدة تحكم Firebase إلى مشروعك كما هو موضح في إضافة Firebase إلى مشروع JavaScript الخاص بك .

مخاوف أمنية

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

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

تمكين تسجيل الدخول برقم الهاتف لمشروع Firebase الخاص بك

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

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

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

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

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

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

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

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

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();

Web namespaced API

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();
  }
});

Web namespaced API

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', {});

Web namespaced API

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.
    // ...
  }
});

Web namespaced API

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;
});

Web namespaced API

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

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

Web modular API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web namespaced API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

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

لبدء تسجيل الدخول برقم الهاتف، قدم للمستخدم واجهة تطالبه بتقديم رقم هاتفه، ثم اتصل بـ signInWithPhoneNumber لمطالبة Firebase بإرسال رمز مصادقة إلى هاتف المستخدم عبر الرسائل القصيرة:

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

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

  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
          // ...
        });

    Web namespaced API

    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 Authentication إرسال رسالة نصية قصيرة تحتوي على رمز التحقق إلى هاتف المستخدم.

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

بعد نجاح الاتصال بـ signInWithPhoneNumber ، اطلب من المستخدم كتابة رمز التحقق الذي تلقاه عبر الرسائل القصيرة. بعد ذلك، قم بتسجيل دخول المستخدم عن طريق تمرير التعليمات البرمجية إلى أسلوب 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?)
  // ...
});

Web namespaced 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?)
  // ...
});

إذا نجحت مكالمة confirm ، فهذا يعني أنه تم تسجيل دخول المستخدم بنجاح.

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

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

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

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

firebase.auth().signInWithCredential(credential);

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

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

  • اختبر مصادقة رقم الهاتف دون استهلاك حصة الاستخدام الخاصة بك.
  • اختبار مصادقة رقم الهاتف دون إرسال رسالة نصية قصيرة فعلية.
  • قم بإجراء اختبارات متتالية باستخدام رقم الهاتف نفسه دون الاختناق. وهذا يقلل من خطر الرفض أثناء عملية مراجعة متجر التطبيقات إذا حدث أن استخدم المراجع نفس رقم الهاتف للاختبار.
  • يمكنك الاختبار بسهولة في بيئات التطوير دون أي جهد إضافي، مثل القدرة على التطوير في محاكي 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.

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

عند اكتمال تسجيل الدخول، يتم إنشاء مستخدم Firebase باستخدام رقم الهاتف هذا. يتمتع المستخدم بنفس السلوك والخصائص التي يتمتع بها مستخدم رقم الهاتف الحقيقي، ويمكنه الوصول إلى Realtime Database/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 Realtime وقواعد أمان التخزين السحابي، يمكنك الحصول على معرف المستخدم الفريد للمستخدم الذي قام بتسجيل الدخول من متغير 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.
});

Web namespaced API

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