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

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

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

قبل از شروع

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

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

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

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

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

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

  1. در کنسول Firebase ، بخش Authentication را باز کنید.
  2. در صفحه Sign-in Method ، روش ورود شماره تلفن را فعال کنید.
  3. در همان صفحه، اگر دامنه ای که برنامه شما را میزبانی می کند در بخش دامنه های تغییر مسیر OAuth فهرست نشده است، دامنه خود را اضافه کنید. توجه داشته باشید که لوکال هاست به عنوان یک دامنه میزبان برای اهداف احراز هویت تلفن مجاز نیست.

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

قبل از اینکه بتوانید با شماره تلفن کاربران وارد سیستم شوید، باید تأییدکننده reCAPTCHA Firebase را راه‌اندازی کنید. Firebase از 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 تنظیم کنید. آزمایش با شماره تلفن های خیالی این مزایا را به همراه دارد:

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

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

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

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

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

تست دستی

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

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

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

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

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

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

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

  • در برنامه‌های شما، روش توصیه‌شده برای اطلاع از وضعیت احراز هویت کاربر، تنظیم یک ناظر بر روی شی Auth است. سپس می توانید اطلاعات اولیه پروفایل کاربر را از شی User دریافت کنید. به مدیریت کاربران مراجعه کنید.

  • در قوانین امنیتی Firebase Realtime Database و Cloud Storage خود، می‌توانید شناسه کاربری منحصر به فرد کاربر واردشده به سیستم را از متغیر 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.
});