با Firebase با شماره تلفن با استفاده از جاوا اسکریپت احراز هویت

شما می‌توانید Firebase Authentication برای ورود کاربر با ارسال پیامک به تلفن کاربر استفاده کنید. کاربر با استفاده از کد یکبار مصرفی که در پیامک وجود دارد، وارد سیستم می‌شود.

ساده‌ترین راه برای افزودن ورود با شماره تلفن به برنامه‌تان، استفاده از FirebaseUI است که شامل یک ویجت ورود به سیستم کشویی است که جریان‌های ورود به سیستم را برای ورود با شماره تلفن و همچنین ورود مبتنی بر رمز عبور و ورود فدرال پیاده‌سازی می‌کند. این سند نحوه پیاده‌سازی جریان ورود به سیستم با شماره تلفن را با استفاده از Firebase SDK شرح می‌دهد.

قبل از اینکه شروع کنی

اگر قبلاً این کار را نکرده‌اید، قطعه کد مقداردهی اولیه را از کنسول Firebase به پروژه خود کپی کنید، همانطور که در بخش «افزودن Firebase به پروژه جاوا اسکریپت» توضیح داده شده است.

نگرانی‌های امنیتی

احراز هویت تنها با استفاده از شماره تلفن، اگرچه راحت است، اما نسبت به سایر روش‌های موجود از امنیت کمتری برخوردار است، زیرا داشتن شماره تلفن می‌تواند به راحتی بین کاربران منتقل شود. همچنین، در دستگاه‌هایی با چندین پروفایل کاربری، هر کاربری که می‌تواند پیامک دریافت کند، می‌تواند با استفاده از شماره تلفن دستگاه وارد یک حساب کاربری شود.

اگر در برنامه خود از ورود به سیستم مبتنی بر شماره تلفن استفاده می‌کنید، باید آن را در کنار روش‌های ورود امن‌تر ارائه دهید و کاربران را از مزایای امنیتی استفاده از ورود به سیستم با شماره تلفن مطلع کنید.

ورود با شماره تلفن را برای پروژه Firebase خود فعال کنید

برای ورود کاربران از طریق پیامک، ابتدا باید روش ورود با شماره تلفن را برای پروژه Firebase خود فعال کنید:

  1. در کنسول Firebase ، بخش Authentication (احراز هویت) را باز کنید.
  2. در صفحه روش ورود ، روش ورود با شماره تلفن را فعال کنید.
  3. در صفحه تنظیمات ، سیاستی را برای مناطقی که می‌خواهید ارسال پیامک به آنها مجاز یا غیرمجاز باشد، تنظیم کنید. برای پروژه‌های جدید، سیاست پیش‌فرض هیچ منطقه‌ای را مجاز نمی‌داند.
  4. در همان صفحه، اگر دامنه‌ای که برنامه شما را میزبانی خواهد کرد در بخش دامنه‌های تغییر مسیر OAuth ذکر نشده است، دامنه خود را اضافه کنید. توجه داشته باشید که localhost به عنوان دامنه میزبانی شده برای اهداف احراز هویت تلفن مجاز نیست.

تأییدکننده reCAPTCHA را تنظیم کنید

قبل از اینکه بتوانید کاربران را با شماره تلفن‌هایشان وارد سیستم کنید، باید تأییدکننده reCAPTCHA فایربیس را تنظیم کنید. فایربیس از reCAPTCHA برای جلوگیری از سوءاستفاده استفاده می‌کند، مثلاً با اطمینان از اینکه درخواست تأیید شماره تلفن از یکی از دامنه‌های مجاز برنامه شما می‌آید.

نیازی نیست که کلاینت reCAPTCHA را به صورت دستی تنظیم کنید؛ وقتی از شیء RecaptchaVerifier در Firebase SDK استفاده می‌کنید، Firebase به طور خودکار هرگونه کلید و رمز کلاینت لازم را ایجاد و مدیریت می‌کند.

شیء RecaptchaVerifier از reCAPTCHA نامرئی پشتیبانی می‌کند، که اغلب می‌تواند کاربر را بدون نیاز به هیچ اقدامی از سوی کاربر تأیید کند، و همچنین از ویجت reCAPTCHA که همیشه برای تکمیل موفقیت‌آمیز به تعامل کاربر نیاز دارد.

reCAPTCHA رندر شده‌ی اصلی را می‌توان با به‌روزرسانی کد زبان در نمونه‌ی Auth قبل از رندر reCAPTCHA، مطابق با ترجیح کاربر بومی‌سازی کرد. بومی‌سازی فوق‌الذکر همچنین در مورد پیامک ارسالی به کاربر که حاوی کد تأیید است، اعمال خواهد شد.

Web

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

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

از reCAPTCHA نامرئی استفاده کنید

برای استفاده از reCAPTCHA نامرئی، یک شیء RecaptchaVerifier با پارامتر size تنظیم شده روی invisible ایجاد کنید، که شناسه دکمه‌ای را که فرم ورود شما را ارسال می‌کند، مشخص می‌کند. برای مثال:

Web

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

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

از ابزارک reCAPTCHA استفاده کنید

برای استفاده از ویجت reCAPTCHA قابل مشاهده، یک عنصر در صفحه خود ایجاد کنید تا ویجت را در خود جای دهد، و سپس یک شیء RecaptchaVerifier ایجاد کنید و هنگام انجام این کار، شناسه کانتینر را مشخص کنید. برای مثال:

Web

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

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

Web

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

اختیاری: پارامترهای reCAPTCHA را مشخص کنید

شما می‌توانید به صورت اختیاری توابع فراخوانی را روی شیء RecaptchaVerifier تنظیم کنید که وقتی کاربر reCAPTCHA را حل می‌کند یا reCAPTCHA قبل از ارسال فرم توسط کاربر منقضی می‌شود، فراخوانی می‌شوند:

Web

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

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

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

Web

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

پس از render ، شناسه ویجت reCAPTCHA را دریافت می‌کنید که می‌توانید از آن برای فراخوانی API reCAPTCHA استفاده کنید:

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

ارسال کد تایید به تلفن کاربر

برای شروع ورود با شماره تلفن، رابطی را به کاربر ارائه دهید که از او بخواهد شماره تلفن خود را ارائه دهد و سپس تابع signInWithPhoneNumber را فراخوانی کنید تا از Firebase بخواهید یک کد احراز هویت را از طریق پیامک به تلفن کاربر ارسال کند:

  1. شماره تلفن کاربر را دریافت کنید.

    الزامات قانونی متفاوت است، اما به عنوان بهترین روش و برای تعیین انتظارات برای کاربران خود، باید به آنها اطلاع دهید که اگر از ورود به سیستم با تلفن استفاده کنند، ممکن است یک پیامک برای تأیید دریافت کنند و نرخ‌های استاندارد اعمال می‌شود.

  2. تابع signInWithPhoneNumber را فراخوانی کنید و شماره تلفن کاربر و RecaptchaVerifier که قبلاً ایجاد کرده‌اید را به آن ارسال کنید.

    Web

    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

    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

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

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 برای حساب کاربر دارید، به جای فراخوانی confirm ، کد تأیید را از نتیجه تأیید و کد تأیید را به PhoneAuthProvider.credential ارسال کنید:

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

سپس، می‌توانید کاربر را با اعتبارنامه وارد سیستم کنید:

firebase.auth().signInWithCredential(credential);

با شماره تلفن‌های فرضی تست کنید

شما می‌توانید از طریق کنسول Firebase شماره تلفن‌های فرضی را برای توسعه تنظیم کنید. تست با شماره تلفن‌های فرضی این مزایا را ارائه می‌دهد:

  • احراز هویت شماره تلفن را بدون مصرف سهمیه استفاده خود آزمایش کنید.
  • احراز هویت شماره تلفن را بدون ارسال پیامک واقعی آزمایش کنید.
  • تست‌های متوالی را با شماره تلفن یکسان و بدون مشکل اجرا کنید. این کار خطر رد شدن در فرآیند بررسی اپ استور را در صورتی که داور از شماره تلفن یکسانی برای آزمایش استفاده کند، به حداقل می‌رساند.
  • به راحتی در محیط‌های توسعه و بدون هیچ تلاش اضافی، مانند امکان توسعه در شبیه‌ساز iOS یا شبیه‌ساز اندروید بدون سرویس‌های Google Play، تست کنید.
  • تست‌های یکپارچه‌سازی را بدون مسدود شدن توسط بررسی‌های امنیتی که معمولاً روی شماره تلفن‌های واقعی در یک محیط عملیاتی اعمال می‌شوند، بنویسید.

شماره تلفن‌های فرضی باید این شرایط را داشته باشند:

  1. مطمئن شوید که از شماره تلفن‌هایی استفاده می‌کنید که واقعاً خیالی هستند و از قبل وجود ندارند. Firebase Authentication به شما اجازه نمی‌دهد شماره تلفن‌های موجود که توسط کاربران واقعی استفاده می‌شوند را به عنوان شماره تلفن آزمایشی تنظیم کنید. یک گزینه این است که از شماره‌های پیشوند ۵۵۵ به عنوان شماره تلفن آزمایشی ایالات متحده استفاده کنید، به عنوان مثال: +1 650-555-3434
  2. شماره تلفن‌ها باید از نظر طول و سایر محدودیت‌ها به درستی قالب‌بندی شوند. آن‌ها همچنان از همان اعتبارسنجی شماره تلفن کاربر واقعی عبور خواهند کرد.
  3. شما می‌توانید تا ۱۰ شماره تلفن برای توسعه اضافه کنید.
  4. از شماره تلفن‌ها/کدهای آزمایشی که حدس زدنشان دشوار است استفاده کنید و مرتباً آنها را تغییر دهید.

شماره تلفن‌ها و کدهای تأیید فرضی ایجاد کنید

  1. در کنسول Firebase ، بخش Authentication (احراز هویت) را باز کنید.
  2. در برگه «روش ورود» ، اگر قبلاً ارائه‌دهنده تلفن را فعال نکرده‌اید، آن را فعال کنید.
  3. منوی آکاردئونی شماره تلفن‌ها برای آزمایش را باز کنید.
  4. شماره تلفنی که می‌خواهید تست کنید را وارد کنید، برای مثال: +1 650-555-3434 .
  5. کد تأیید ۶ رقمی را برای آن شماره خاص وارد کنید، مثلاً: ۶۵۴۳۲۱ .
  6. شماره را اضافه کنید . در صورت نیاز، می‌توانید شماره تلفن و کد آن را با نگه داشتن ماوس روی ردیف مربوطه و کلیک روی نماد سطل زباله حذف کنید.

تست دستی

شما می‌توانید مستقیماً از یک شماره تلفن فرضی در برنامه خود استفاده کنید. این به شما امکان می‌دهد در طول مراحل توسعه، بدون مواجهه با مشکلات سهمیه‌بندی یا محدودیت سرعت، تست دستی انجام دهید. همچنین می‌توانید مستقیماً از یک شبیه‌ساز iOS یا شبیه‌ساز اندروید بدون نصب سرویس‌های Google Play، تست را انجام دهید.

وقتی شماره تلفن فرضی را وارد می‌کنید و کد تأیید را ارسال می‌کنید، هیچ پیامکی ارسال نمی‌شود. در عوض، برای تکمیل ورود به سیستم باید کد تأیید پیکربندی‌شده قبلی را وارد کنید.

پس از تکمیل ورود به سیستم، یک کاربر Firebase با آن شماره تلفن ایجاد می‌شود. این کاربر همان رفتار و ویژگی‌های یک کاربر شماره تلفن واقعی را دارد و می‌تواند به همان روش به Realtime Database / Cloud Firestore و سایر سرویس‌ها دسترسی داشته باشد. توکن شناسه ایجاد شده در طول این فرآیند، همان امضای یک کاربر شماره تلفن واقعی را دارد.

گزینه دیگر این است که اگر می‌خواهید دسترسی را بیشتر محدود کنید، یک نقش آزمایشی از طریق ادعاهای سفارشی روی این کاربران تنظیم کنید تا آنها را به عنوان کاربران جعلی متمایز کنید.

تست یکپارچه‌سازی

علاوه بر تست دستی، Firebase Authentication رابط‌های برنامه‌نویسی کاربردی (API) را برای کمک به نوشتن تست‌های یکپارچه‌سازی برای تست احراز هویت تلفن ارائه می‌دهد. این APIها با غیرفعال کردن الزام reCAPTCHA در وب و اعلان‌های بی‌صدا در iOS، تأیید برنامه را غیرفعال می‌کنند. این امر تست خودکار را در این جریان‌ها امکان‌پذیر و پیاده‌سازی آن را آسان‌تر می‌کند. علاوه بر این، آنها به فراهم کردن امکان آزمایش جریان‌های تأیید فوری در اندروید کمک می‌کنند.

در وب، قبل از رندر کردن firebase.auth.RecaptchaVerifier ، appVerificationDisabledForTesting روی true تنظیم کنید. این کار reCAPTCHA را به طور خودکار حل می‌کند و به شما امکان می‌دهد شماره تلفن را بدون حل دستی آن ارسال کنید. توجه داشته باشید که حتی اگر reCAPTCHA غیرفعال باشد، استفاده از شماره تلفن غیر تخیلی همچنان باعث عدم تکمیل ورود به سیستم می‌شود. فقط شماره تلفن‌های تخیلی را می‌توان با این API استفاده کرد.

// 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 شما ذخیره می‌شود و می‌تواند برای شناسایی کاربر در هر برنامه در پروژه شما، صرف نظر از نحوه ورود کاربر، مورد استفاده قرار گیرد.

  • در برنامه‌های شما، روش پیشنهادی برای اطلاع از وضعیت احراز هویت کاربر، تنظیم یک ناظر (observer) روی شیء Auth است. سپس می‌توانید اطلاعات اولیه پروفایل کاربر را از شیء User دریافت کنید. به بخش مدیریت کاربران (Manage Users) مراجعه کنید.

  • در قوانین امنیتی پایگاه داده و Cloud Storage Firebase Realtime Database ، می‌توانید شناسه کاربری منحصر به فرد کاربر وارد شده را از متغیر auth دریافت کنید و از آن برای کنترل داده‌هایی که کاربر می‌تواند به آنها دسترسی داشته باشد، استفاده کنید.

شما می‌توانید با پیوند دادن اعتبارنامه‌های ارائه‌دهنده‌ی احراز هویت به یک حساب کاربری موجود، به کاربران اجازه دهید با استفاده از چندین ارائه‌دهنده‌ی احراز هویت به برنامه‌ی شما وارد شوند.

برای خروج کاربر، signOut را فراخوانی کنید:

Web

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

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

Web

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