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

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

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

قبل از شروع

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

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

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

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

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

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

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

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

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

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

  1. در Xcode، اعلان‌های لحظه‌ای را برای پروژه‌تان فعال کنید.
  2. گواهی APN خود را در 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).
        // There's no need for the end user to input the verification code manually.
        // `credential` can't 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();