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

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

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

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

  1. اگر هنوز برنامه خود را به پروژه Firebase خود متصل نکرده‌اید، این کار را از کنسول Firebase انجام دهید.
  2. برای نصب و مدیریت وابستگی‌های Firebase از Swift Package Manager استفاده کنید.

    1. در Xcode، با باز کردن پروژه برنامه خود، به File > Add Packages بروید.
    2. وقتی از شما خواسته شد، مخزن SDK پلتفرم‌های اپل فایربیس را اضافه کنید:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. کتابخانه Firebase Authentication را انتخاب کنید.
    5. پرچم -ObjC را به بخش Other Linker Flags در تنظیمات ساخت هدف خود اضافه کنید.
    6. پس از اتمام، Xcode به طور خودکار شروع به حل و دانلود وابستگی‌های شما در پس‌زمینه می‌کند.

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

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

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

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

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

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

فعال کردن تأیید برنامه

برای استفاده از احراز هویت با شماره تلفن، فایربیس باید بتواند تأیید کند که درخواست‌های ورود با شماره تلفن از برنامه شما می‌آیند. دو روش برای انجام این کار Firebase Authentication وجود دارد:

  • اعلان‌های بی‌صدای APNها : وقتی برای اولین بار با شماره تلفن کاربری در دستگاهی وارد سیستم می‌شوید، Firebase Authentication با استفاده از یک اعلان بی‌صدا، یک توکن به دستگاه ارسال می‌کند. اگر برنامه شما با موفقیت اعلان را از فایربیس دریافت کند، ورود با شماره تلفن می‌تواند ادامه یابد.

    برای iOS 8.0 و جدیدتر، اعلان‌های بی‌صدا نیازی به رضایت صریح کاربر ندارند و بنابراین تحت تأثیر عدم تمایل کاربر به دریافت اعلان‌های APN در برنامه قرار نمی‌گیرند. بنابراین، برنامه هنگام پیاده‌سازی احراز هویت شماره تلفن Firebase نیازی به درخواست اجازه کاربر برای دریافت اعلان‌های فوری ندارد.

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

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

شروع دریافت اعلان‌های بی‌صدا

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

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

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

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

    3. به محلی که کلید خود را ذخیره کرده‌اید بروید، آن را انتخاب کنید و روی «باز کردن» کلیک کنید. شناسه کلید را برای کلید (که در مرکز اعضای توسعه‌دهنده اپل موجود است) اضافه کنید و روی «بارگذاری» کلیک کنید.

    اگر از قبل گواهی APN دارید، می‌توانید به جای آن گواهی را آپلود کنید.

  3. در Xcode، قابلیت حالت‌های پس‌زمینه (Background Modes) را برای پروژه خود فعال کنید و سپس کادرهای انتخاب مربوط به حالت‌های دریافت پس‌زمینه (Background fetch) و اعلان‌های از راه دور (Remote notifications) را علامت بزنید.

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

برای فعال کردن Firebase SDK برای استفاده از تأیید reCAPTCHA:

  1. طرح‌های URL سفارشی را به پروژه Xcode خود اضافه کنید:
    1. پیکربندی پروژه خود را باز کنید: روی نام پروژه در نمای درختی سمت چپ دوبار کلیک کنید. برنامه خود را از بخش TARGETS انتخاب کنید، سپس تب Info را انتخاب کنید و بخش URL Types را باز کنید.
    2. روی دکمه + کلیک کنید و شناسه برنامه رمزگذاری شده خود را به عنوان یک طرح URL اضافه کنید. می‌توانید شناسه برنامه رمزگذاری شده خود را در صفحه تنظیمات عمومی کنسول Firebase، در بخش برنامه iOS خود پیدا کنید. سایر فیلدها را خالی بگذارید.

      پس از تکمیل، پیکربندی شما باید چیزی شبیه به موارد زیر باشد (اما با مقادیر خاص برنامه شما):

      تصویری از رابط کاربری تنظیم طرح URL سفارشی Xcode
  2. اختیاری : اگر می‌خواهید نحوه نمایش SFSafariViewController توسط برنامه خود را هنگام نمایش reCAPTCHA به کاربر سفارشی کنید، یک کلاس سفارشی ایجاد کنید که با پروتکل AuthUIDelegate مطابقت داشته باشد و آن را به verifyPhoneNumber(_:uiDelegate:completion:) ارسال کنید.

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

برای شروع ورود با شماره تلفن، رابطی را به کاربر ارائه دهید که از او بخواهد شماره تلفن خود را ارائه دهد و سپس تابع verifyPhoneNumber(_:uiDelegate:completion:) را فراخوانی کنید تا از Firebase بخواهید یک کد احراز هویت را از طریق پیامک به تلفن کاربر ارسال کند:

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

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

  2. تابع verifyPhoneNumber(_:uiDelegate:completion:) را فراخوانی کنید و شماره تلفن کاربر را به آن ارسال کنید.

    سویفت

    PhoneAuthProvider.provider()
      .verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
          if let error = error {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // Sign in using the verificationID and the code sent to the user
          // ...
      }

    هدف-سی

    [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput
                                            UIDelegate:nil
                                            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
      if (error) {
        [self showMessagePrompt:error.localizedDescription];
        return;
      }
      // Sign in using the verificationID and the code sent to the user
      // ...
    }];

    متد verifyPhoneNumber از نوع reentrant است: اگر چندین بار آن را فراخوانی کنید، مثلاً در متد onAppear یک view، متد verifyPhoneNumber پیامک دوم را ارسال نمی‌کند، مگر اینکه زمان درخواست اصلی به پایان رسیده باشد.

    وقتی تابع verifyPhoneNumber(_:uiDelegate:completion:) فراخوانی می‌کنید، فایربیس یک اعلان بی‌صدا به برنامه شما ارسال می‌کند یا یک چالش reCAPTCHA برای کاربر ایجاد می‌کند. پس از اینکه برنامه شما اعلان را دریافت کرد یا کاربر چالش reCAPTCHA را تکمیل کرد، فایربیس یک پیامک حاوی کد احراز هویت به شماره تلفن مشخص شده ارسال می‌کند و یک شناسه تأیید را به تابع تکمیل شما ارسال می‌کند. برای ورود کاربر به سیستم، به کد تأیید و شناسه تأیید نیاز خواهید داشت.

    پیام SMS ارسال شده توسط Firebase همچنین می‌تواند با مشخص کردن زبان auth از طریق ویژگی languageCode در نمونه Auth شما، بومی‌سازی شود.

    سویفت

     // Change language code to french.
     Auth.auth().languageCode = "fr";

    هدف-سی

     // Change language code to french.
     [FIRAuth auth].languageCode = @"fr";
  3. شناسه تأیید را ذخیره کنید و هنگام بارگیری برنامه، آن را بازیابی کنید. با انجام این کار، می‌توانید مطمئن شوید که اگر برنامه شما قبل از تکمیل فرآیند ورود کاربر (مثلاً هنگام تغییر به برنامه پیامک) خاتمه یابد، هنوز شناسه تأیید معتبری دارید.

    شما می‌توانید شناسه تأیید را به هر روشی که می‌خواهید حفظ کنید. یک راه ساده، ذخیره شناسه تأیید با شیء NSUserDefaults است:

    سویفت

    UserDefaults.standard.set(verificationID, forKey: "authVerificationID")

    هدف-سی

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:verificationID forKey:@"authVerificationID"];

    سپس، می‌توانید مقدار ذخیره شده را بازیابی کنید:

    سویفت

    let verificationID = UserDefaults.standard.string(forKey: "authVerificationID")

    هدف-سی

    NSString *verificationID = [defaults stringForKey:@"authVerificationID"];

اگر فراخوانی تابع verifyPhoneNumber(_:uiDelegate:completion:) با موفقیت انجام شود، می‌توانید از کاربر بخواهید که هنگام دریافت کد تأیید در پیامک، آن را تایپ کند.

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

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

  1. کد تایید را از کاربر دریافت کنید.
  2. یک شیء FIRPhoneAuthCredential از کد تأیید و شناسه تأیید ایجاد کنید.

    سویفت

    let credential = PhoneAuthProvider.provider().credential(
      withVerificationID: verificationID,
      verificationCode: verificationCode
    )

    هدف-سی

    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. کاربر را با شیء FIRPhoneAuthCredential وارد سیستم کنید:

    سویفت

    Auth.auth().signIn(with: credential) { authResult, error in
        if let error = error {
          let authError = error as NSError
          if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue {
            // The user is a multi-factor user. Second factor challenge is required.
            let resolver = authError
              .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
            var displayNameString = ""
            for tmpFactorInfo in resolver.hints {
              displayNameString += tmpFactorInfo.displayName ?? ""
              displayNameString += " "
            }
            self.showTextInputPrompt(
              withMessage: "Select factor to sign in\n\(displayNameString)",
              completionBlock: { userPressedOK, displayName in
                var selectedHint: PhoneMultiFactorInfo?
                for tmpFactorInfo in resolver.hints {
                  if displayName == tmpFactorInfo.displayName {
                    selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo
                  }
                }
                PhoneAuthProvider.provider()
                  .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil,
                                     multiFactorSession: resolver
                                       .session) { verificationID, error in
                    if error != nil {
                      print(
                        "Multi factor start sign in failed. Error: \(error.debugDescription)"
                      )
                    } else {
                      self.showTextInputPrompt(
                        withMessage: "Verification code for \(selectedHint?.displayName ?? "")",
                        completionBlock: { userPressedOK, verificationCode in
                          let credential: PhoneAuthCredential? = PhoneAuthProvider.provider()
                            .credential(withVerificationID: verificationID!,
                                        verificationCode: verificationCode!)
                          let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator
                            .assertion(with: credential!)
                          resolver.resolveSignIn(with: assertion!) { authResult, error in
                            if error != nil {
                              print(
                                "Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
                              )
                            } else {
                              self.navigationController?.popViewController(animated: true)
                            }
                          }
                        }
                      )
                    }
                  }
              }
            )
          } else {
            self.showMessagePrompt(error.localizedDescription)
            return
          }
          // ...
          return
        }
        // User is signed in
        // ...
    }

    هدف-سی

    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult,
                                           NSError * _Nullable error) {
        if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
          FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
          NSMutableString *displayNameString = [NSMutableString string];
          for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
            [displayNameString appendString:tmpFactorInfo.displayName];
            [displayNameString appendString:@" "];
          }
          [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                               completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
           FIRPhoneMultiFactorInfo* selectedHint;
           for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
             if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
               selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
             }
           }
           [FIRPhoneAuthProvider.provider
            verifyPhoneNumberWithMultiFactorInfo:selectedHint
            UIDelegate:nil
            multiFactorSession:resolver.session
            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
              if (error) {
                [self showMessagePrompt:error.localizedDescription];
              } else {
                [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                     completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
                 FIRPhoneAuthCredential *credential =
                     [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                                  verificationCode:verificationCode];
                 FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
                 [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
                   if (error) {
                     [self showMessagePrompt:error.localizedDescription];
                   } else {
                     NSLog(@"Multi factor finanlize sign in succeeded.");
                   }
                 }];
               }];
              }
            }];
         }];
        }
      else if (error) {
        // ...
        return;
      }
      // User successfully signed in. Get user data from the FIRUser object
      if (authResult == nil) { return; }
      FIRUser *user = authResult.user;
      // ...
    }];

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

شما می‌توانید از طریق کنسول 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، تأیید برنامه را غیرفعال می‌کنند. این امر تست خودکار را در این جریان‌ها امکان‌پذیر و پیاده‌سازی آن را آسان‌تر می‌کند. علاوه بر این، آنها به فراهم کردن امکان آزمایش جریان‌های تأیید فوری در اندروید کمک می‌کنند.

در iOS، قبل از فراخوانی verifyPhoneNumber ، باید تنظیمات appVerificationDisabledForTesting روی TRUE تنظیم شود. این کار بدون نیاز به هیچ توکن APN یا ارسال اعلان‌های بی‌صدا در پس‌زمینه پردازش می‌شود و آزمایش آن را در یک شبیه‌ساز آسان‌تر می‌کند. این کار همچنین جریان جایگزین reCAPTCHA را غیرفعال می‌کند.

توجه داشته باشید که وقتی تأیید برنامه غیرفعال باشد، استفاده از شماره تلفن غیرواقعی باعث عدم تکمیل ورود به سیستم می‌شود. فقط شماره تلفن‌های خیالی را می‌توان با این API استفاده کرد.

سویفت

let phoneNumber = "+16505554567"

// This test verification code is specified for the given test phone number in the developer console.
let testVerificationCode = "123456"

Auth.auth().settings.isAppVerificationDisabledForTesting = true
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) {
                                                            verificationID, error in
    if let error = error {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signIn(with: credential) { authResult, error in
      if let error = error {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authResult.user
    };
};

هدف-سی

NSString *phoneNumber = @"+16505554567";

// This test verification code is specified for the given test phone number in the developer console.
NSString *testVerificationCode = @"123456";

[FIRAuth auth].settings.appVerificationDisabledForTesting = YES;
[[FIRPhoneAuthProvider provider] verifyPhoneNumber:phoneNumber
                                        completion:^(NSString *_Nullable verificationID,
                                                     NSError *_Nullable error) {
    if (error) {
      // Handles error
      [self handleError:error];
      return;
    }
    FIRAuthCredential *credential =
        [FIRPhoneAuthProvider credentialWithVerificationID:verificationID
                                          verificationCode:testVerificationCode];
    [FIRAuth auth] signInWithAndRetrieveDataWithCredential:credential
                                                completion:^(FIRUser *_Nullable user,
                                                             NSError *_Nullable error) {
      if (error) {
        // Handles error
        [self handleError:error];
        return;
      }
      _user = user;
    }];
}];

پیوست: استفاده از ورود به سیستم با تلفن بدون استفاده از دکمه Swizzling

Firebase Authentication از متد swizzling برای دریافت خودکار توکن APN برنامه شما، مدیریت اعلان‌های بی‌صدا که فایربیس به برنامه شما ارسال می‌کند و رهگیری خودکار تغییر مسیر طرح سفارشی از صفحه تأیید reCAPTCHA در حین تأیید استفاده می‌کند.

اگر ترجیح می‌دهید از swizzling استفاده نکنید، می‌توانید با اضافه کردن flag FirebaseAppDelegateProxyEnabled به فایل Info.plist برنامه خود و تنظیم آن روی NO ، آن را غیرفعال کنید. توجه داشته باشید که تنظیم این flag روی NO swizzling را برای سایر محصولات Firebase، از جمله Firebase Cloud Messaging ، نیز غیرفعال می‌کند.

اگر swizzling را غیرفعال کنید، باید توکن دستگاه APN، اعلان‌های فوری و طرح سفارشی تغییر مسیر URL را به Firebase Authentication ارسال کنید.

اگر در حال ساخت یک برنامه SwiftUI هستید، باید توکن دستگاه APNها، اعلان‌های فوری و URL تغییر مسیر طرح سفارشی را نیز به Firebase Authentication ارسال کنید.

برای به دست آوردن توکن دستگاه APN، متد application(_:didRegisterForRemoteNotificationsWithDeviceToken:) پیاده‌سازی کنید و در آن، توکن دستگاه را به متد setAPNSToken(_:type:) در Auth ارسال کنید.

سویفت

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  // Pass device token to auth
  Auth.auth().setAPNSToken(deviceToken, type: .unknown)

  // Further handling of the device token if needed by the app
  // ...
}

هدف-سی

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  // Pass device token to auth.
  [[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];
  // Further handling of the device token if needed by the app.
}

برای مدیریت اعلان‌های فوری، در متد application(_:didReceiveRemoteNotification:fetchCompletionHandler:): با فراخوانی متد canHandleNotification(_:) در Auth ، اعلان‌های مرتبط با احراز هویت Firebase را بررسی کنید.

سویفت

func application(_ application: UIApplication,
    didReceiveRemoteNotification notification: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  if Auth.auth().canHandleNotification(notification) {
    completionHandler(.noData)
    return
  }
  // This notification is not auth related; it should be handled separately.
}

هدف-سی

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)notification
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // Pass notification to auth and check if they can handle it.
  if ([[FIRAuth auth] canHandleNotification:notification]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return;
  }
  // This notification is not auth related; it should be handled separately.
}

برای مدیریت URL تغییر مسیر با طرح سفارشی، متد application(_:open:options:) را پیاده‌سازی کنید و در آن‌ها، URL را به متد canHandleURL(_:) در Auth ارسال کنید.

سویفت

func application(_ application: UIApplication, open url: URL,
    options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
  if Auth.auth().canHandle(url) {
    return true
  }
  // URL not auth related; it should be handled separately.
}

هدف-سی

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  if ([[FIRAuth auth] canHandleURL:url]) {
    return YES;
  }
  // URL not auth related; it should be handled separately.
}

اگر از SwiftUI یا UISceneDelegate استفاده می‌کنید، برای مدیریت URL تغییر مسیر، متد scene(_:openURLContexts:) را پیاده‌سازی کنید و در آنها، URL را به متد canHandleURL(_:) در Auth ارسال کنید.

سویفت

func scene(_ scene: UIScene, openURLContexts URLContexts: Set&ltUIOpenURLContext&gt) {
  for urlContext in URLContexts {
      let url = urlContext.url
      _ = Auth.auth().canHandle(url)
  }
  // URL not auth related; it should be handled separately.
}

هدف-سی

- (void)scene:(UIScene *)scene openURLContexts:(NSSet&ltUIOpenURLContext *&gt *)URLContexts {
  for (UIOpenURLContext *urlContext in URLContexts) {
    [FIRAuth.auth canHandleURL:urlContext.url];
    // URL not auth related; it should be handled separately.
  }
}

مراحل بعدی

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

  • در برنامه‌های خود، می‌توانید اطلاعات اولیه پروفایل کاربر را از شیء User دریافت کنید. به بخش مدیریت کاربران مراجعه کنید.

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

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

برای خروج از سیستم کاربر، تابع signOut: را فراخوانی کنید.

سویفت

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

هدف-سی

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

همچنین می‌توانید کد مدیریت خطا را برای طیف کامل خطاهای احراز هویت اضافه کنید. به بخش مدیریت خطاها مراجعه کنید.