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

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

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

قبل از شروع

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

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

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

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

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

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

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

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

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

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

  1. در Xcode، اعلان‌های لحظه‌ای را برای پروژه‌تان فعال کنید.
  2. گواهینامه APNs خود را در Firebase بارگذاری کنید. اگر ازقبل گواهینامه APNs ندارید، حتماً در مرکز اعضای توسعه‌دهندگان Apple گواهینامه‌ای ایجاد کنید.

    1. در کنسول Firebase، به تنظیمات > کلی بروید. سپس، روی زبانه «پیام‌رسانی ابری» کلیک کنید.
    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 تماس می‌گیرید، Firebase،
    • (در iOS) اعلان لحظه‌ای بی‌صدایی به برنامه‌تان ارسال می‌کند،
    • پیامکی حاوی کد اصالت‌سنجی به شماره تلفن مشخص‌شده ارسال می‌کند و شناسه درستی‌سنجی را به تابع تکمیل شما منتقل می‌کند. برای ورود به سیستم کاربر، به کد درستی‌سنجی و شناسه درستی‌سنجی نیاز خواهید داشت.
  3. شناسه درستی‌سنجی را ذخیره کنید و وقتی برنامه بار می‌شود آن را بازیابی کنید. با انجام این کار، می‌توانید مطمئن شوید که اگر برنامه شما قبل‌از اینکه کاربر جریان ورود به سیستم را تکمیل کند بسته شود (برای مثال، هنگام رفتن به برنامه پیامک)، همچنان شناسه درستی‌سنجی معتبری داشته باشید.

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

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

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

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

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

auth->SignOut();