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

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

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

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

  1. فایربیس را به پروژه ++C خود اضافه کنید .
  2. اگر هنوز برنامه خود را به پروژه Firebase خود متصل نکرده‌اید، این کار را از کنسول Firebase انجام دهید.
  3. الزامات پلتفرم برای ورود به سیستم با شماره تلفن را درک کنید:
    • ورود با شماره تلفن فقط برای پلتفرم‌های موبایل است.
    • در iOS، ورود با شماره تلفن به یک دستگاه فیزیکی نیاز دارد و روی شبیه‌ساز کار نمی‌کند.

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

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

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

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

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

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

شروع دریافت اعلان‌های APN (پلتفرم‌های اپل)

برای استفاده از احراز هویت با شماره تلفن در پلتفرم‌های اپل، برنامه شما باید بتواند اعلان‌های APN را از Firebase دریافت کند. وقتی برای اولین بار با شماره تلفن کاربری در دستگاهی وارد سیستم می‌شوید، Firebase Authentication یک اعلان بی‌صدا به دستگاه ارسال می‌کند تا تأیید کند که درخواست ورود با شماره تلفن از برنامه شما آمده است. (به همین دلیل، ورود با شماره تلفن را نمی‌توان در شبیه‌ساز استفاده کرد.)

برای فعال کردن اعلان‌های APN برای استفاده با Firebase Authentication :

  1. در Xcode، اعلان‌های فوری (push notifications) را برای پروژه خود فعال کنید .
  2. گواهی APN خود را در Firebase آپلود کنید. اگر از قبل گواهی APN ندارید، حتماً آن را در مرکز اعضای توسعه‌دهنده اپل ایجاد کنید.

    1. در داخل پروژه خود در کنسول Firebase ، نماد چرخ دنده را انتخاب کنید، تنظیمات پروژه را انتخاب کنید و سپس برگه Cloud Messaging را انتخاب کنید.

    2. دکمه آپلود گواهی را برای گواهی توسعه، گواهی تولید یا هر دو انتخاب کنید. حداقل یکی از آنها لازم است.

    3. برای هر گواهی، فایل .p12 را انتخاب کنید و در صورت وجود، رمز عبور را وارد کنید. مطمئن شوید که شناسه بسته این گواهی با شناسه بسته برنامه شما مطابقت دارد. ذخیره را انتخاب کنید.

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

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

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

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

  2. فراخوانی PhoneAuthProvider::VerifyPhoneNumber و ارسال شماره تلفن کاربر به آن.
    class PhoneListener : public PhoneAuthProvider::Listener {
     public:
      ~PhoneListener() override {}
    
      void OnVerificationCompleted(PhoneAuthCredential credential) override {
        // Auto-sms-retrieval or instant validation has succeeded (Android only).
        // No need for the user to input the verification code manually.
        // `credential` can be used instead of calling GetCredential().
      }
    
      void OnVerificationFailed(const std::string& error) override {
        // Verification code not sent.
      }
    
      void OnCodeSent(const std::string& verification_id,
                      const PhoneAuthProvider::ForceResendingToken&
                          force_resending_token) override {
        // Verification code successfully sent via SMS.
        // Show the Screen to enter the Code.
        // Developer may want to save that verification_id along with other app states in case
        // the app is terminated before the user gets the SMS verification code.
      }
    };
    
    PhoneListener phone_listener;
    PhoneAuhtOptions options;
    options.timeout_milliseconds = kAutoVerifyTimeOut;
    options.phone_number = phone_number;
    PhoneAuthProvider& phone_provider = PhoneAuthProvider::GetInstance(auth);
    phone_provider->VerifyPhoneNumber(options, &phone_listener);
    وقتی PhoneAuthProvider::VerifyPhoneNumber در فایربیس فراخوانی می‌کنید،
    • (در iOS) یک اعلان بی‌صدا به برنامه شما ارسال می‌کند،
    • یک پیامک حاوی کد احراز هویت به شماره تلفن مشخص شده ارسال می‌کند و یک شناسه تأیید را به تابع تکمیل شما ارسال می‌کند. برای ورود کاربر، به کد تأیید و شناسه تأیید نیاز خواهید داشت.
  3. شناسه تأیید را ذخیره کنید و هنگام بارگیری برنامه، آن را بازیابی کنید. با انجام این کار، می‌توانید مطمئن شوید که اگر برنامه شما قبل از تکمیل فرآیند ورود کاربر (مثلاً هنگام تغییر به برنامه پیامک) خاتمه یابد، هنوز شناسه تأیید معتبری دارید.

    شما می‌توانید شناسه تأیید را به هر روشی که می‌خواهید حفظ کنید. اگر با یک چارچوب C++ چند پلتفرمی می‌نویسید، باید اعلان‌هایی برای خاتمه و بازیابی برنامه ارائه دهد. در این رویدادها، می‌توانید به ترتیب شناسه تأیید را ذخیره و بازیابی کنید.

اگر فراخوانی VerifyPhoneNumber منجر به فراخوانی OnCodeSent در Listener شما شود، می‌توانید از کاربر بخواهید که هنگام دریافت کد تأیید در پیامک، آن را تایپ کند.

از سوی دیگر، اگر فراخوانی VerifyPhoneNumber منجر به OnVerificationCompleted شود، تأیید خودکار با موفقیت انجام شده است و اکنون یک PhoneAuthCredential خواهید داشت که می‌توانید مطابق توضیحات زیر از آن استفاده کنید.

کاربر با کد تأیید وارد سیستم شود

پس از اینکه کاربر کد تأیید را از طریق پیامک به برنامه شما ارائه داد، با ایجاد یک شیء PhoneAuthCredential از کد تأیید و شناسه تأیید و ارسال آن شیء به Auth::SignInWithCredential ، کاربر را وارد سیستم کنید.

  1. کد تایید را از کاربر دریافت کنید.
  2. یک شیء Credential از کد تأیید و شناسه تأیید ایجاد کنید.
    PhoneAuthCredential credential = phone_auth_provider->GetCredential(
        verification_id_.c_str(), verification_code.c_str());
        
  3. کاربر را با شیء Credential وارد سیستم کنید:
    Future<User> future = auth_->SignInWithCredential(credential);
    future.OnCompletion(
        [](const Future<User*>& result, void*) {
          if (result.error() == kAuthErrorNone) {
            // Successful.
            // User is signed in.
            User user = *result.result();
    
            // This should display the phone number.
            printf("Phone number: %s", user.phone_number().c_str());
    
            // The phone number provider UID is the phone number itself.
            printf("Phone provider uid: %s", user.uid().c_str());
    
            // The phone number providerID is 'phone'
            printf("Phone provider ID: %s", user.provider_id().c_str());
          } else {
            // Error.
            printf("Sign in error: %s", result.error_message().c_str());
          }
        },
        nullptr);

مراحل بعدی

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

  • در برنامه‌های خود، می‌توانید اطلاعات اولیه پروفایل کاربر را از firebase::auth::User دریافت کنید:

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // The user's ID, unique to the Firebase project.
      // Do NOT use this value to authenticate with your backend server,
      // if you have one. Use firebase::auth::User::Token() instead.
      std::string uid = user.uid();
    }
  • در قوانین امنیتی پایگاه داده و Cloud Storage Firebase Realtime Database ، می‌توانید شناسه کاربری منحصر به فرد کاربر وارد شده را از متغیر auth دریافت کنید و از آن برای کنترل داده‌هایی که کاربر می‌تواند به آنها دسترسی داشته باشد، استفاده کنید.

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

برای خروج کاربر، تابع SignOut() فراخوانی کنید:

auth->SignOut();