اصالت‌سنجی با Firebase بااستفاده از پیوند ایمیل در پلاتفرم‌های Apple

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

مزایای متعددی برای ورود به سیستم ازطریق ایمیل وجود دارد:

  • ثبت‌نام و ورود به سیستم بدون دردسر.
  • خطر استفاده مجدد از گذرواژه در برنامه‌ها کاهش می‌یابد، که می‌تواند امنیت حتی گذرواژه‌های خوب انتخاب‌شده را تضعیف کند.
  • توانایی اصالت‌سنجی کاربر و درعین‌حال درستی‌سنجی اینکه کاربر مالک قانونی نشانی ایمیل است.
  • کاربر فقط به یک حساب ایمیل دردسترس برای ورود به سیستم نیاز دارد. مالکیت شماره تلفن یا حساب رسانه‌های اجتماعی لازم نیست.
  • کاربر می‌تواند بدون نیاز به ارائه (یا به‌خاطر سپردن) گذرواژه، که در دستگاه همراه می‌تواند دردسرساز باشد، به‌طور ایمن به سیستم وارد شود.
  • کاربر موجودی که قبلاً با شناسه ایمیل (گذرواژه یا فدرال) به سیستم وارد شده است می‌تواند به ورود به سیستم فقط با ایمیل ارتقا یابد. برای مثال، کاربری که گذرواژه‌اش را فراموش کرده است همچنان می‌تواند بدون نیاز به بازنشانی گذرواژه به سیستم وارد شود.

قبل از شروع

از «مدیر بسته Swift» برای نصب و مدیریت وابستگی‌های Firebase استفاده کنید.

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

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

  1. در کنسول Firebase، به امنیت > اصالت‌سنجی بروید.

  2. در برگه روش ورود به سیستم، ارائه‌دهنده ورود به سیستم ایمیل/گذرواژه را فعال کنید. توجه داشته باشید که برای استفاده از ورود به سیستم با پیوند ایمیل، باید ورود به سیستم با ایمیل/گذرواژه فعال باشد.

  3. در همان بخش، ارائه‌دهنده پیوند ایمیل (ورود به سیستم بدون گذرواژه) را فعال کنید.

  4. روی ذخیره کردن کلیک کنید.

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

  1. شیء ActionCodeSettings را بسازید که دستورالعمل‌های لازم برای ساختن پیوند ایمیل را به Firebase ارائه می‌دهد. فیلدهای زیر را تنظیم کنید:

    • ‫url: پیوند عمیق برای جاسازی و هر وضعیت اضافی که باید منتقل شود. اگر قبلاً این کار را نکرده‌اید، دامنه خود را به فهرست دامنه‌های مجاز اضافه کنید:

      1. در کنسول Firebase، به امنیت > اصالت‌سنجی > زبانه تنظیمات بروید.

      2. در بخش دامنه‌های مجاز، روی افزودن دامنه کلیک کنید و دامنه خود را اضافه کنید.

    • ‫iOSBundleID و androidPackageName: به Firebase Authentication کمک می‌کند تعیین کند پیوند فقط وب یا پیوند تلفن همراه ایجاد کند که در دستگاه Android یا Apple باز می‌شود.
    • ‫handleCodeInApp: روی درست تنظیم کنید. برخلاف دیگر اقدامات ایمیلی خارج از باند (بازنشانی گذرواژه و درستی‌سنجی ایمیل)، عملیات ورود به سیستم همیشه باید در برنامه تکمیل شود. به‌دلیل اینکه در پایان جریان، کاربر باید به سیستم وارد شده باشد و وضعیت «احراز هویت» او در برنامه حفظ شده باشد.
    • linkDomain: وقتی دامنه‌های پیوند Hosting سفارشی برای پروژه‌ای تعریف می‌شود، مشخص کنید که وقتی پیوند باید با برنامه تلفن همراه مشخصی باز شود از کدام دامنه استفاده شود. درغیراین‌صورت، دامنه پیش‌فرض به‌طور خودکار انتخاب می‌شود (برای مثال، PROJECT_ID.firebaseapp.com).
    • ‫dynamicLinkDomain: منسوخ. این پارامتر را مشخص نکنید.

    Swift

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.url = URL(string: "https://www.example.com")
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
    actionCodeSettings.setAndroidPackageName("com.example.android",
                                             installIfNotAvailable: false, minimumVersion: "12")

    Objective-C

    FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
    [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]];
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = YES;
    [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]];
    [actionCodeSettings setAndroidPackageName:@"com.example.android"
                        installIfNotAvailable:NO
                               minimumVersion:@"12"];

    برای کسب اطلاعات بیشتر درباره ActionCodeSettings، به بخش گذراندن وضعیت در کنش‌های ایمیل مراجعه کنید.

  2. نشانی ایمیل کاربر را بپرسید.

  3. پیوند اصالت‌سنجی را به ایمیل کاربر ارسال کنید و ایمیل کاربر را ذخیره کنید تا درصورتی‌که کاربر ورود به سیستم با ایمیل را در همان دستگاه تکمیل کند، از آن استفاده شود.

    Swift

    Auth.auth().sendSignInLink(toEmail: email,
                               actionCodeSettings: actionCodeSettings) { error in
      // ...
        if let error = error {
          self.showMessagePrompt(error.localizedDescription)
          return
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        UserDefaults.standard.set(email, forKey: "Email")
        self.showMessagePrompt("Check your email for link")
        // ...
    }

    Objective-C

    [[FIRAuth auth] sendSignInLinkToEmail:email
                       actionCodeSettings:actionCodeSettings
                               completion:^(NSError *_Nullable error) {
      // ...
        if (error) {
          [self showMessagePrompt:error.localizedDescription];
           return;
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"];
        [self showMessagePrompt:@"Check your email for link"];
        // ...
    }];

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

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

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

پس‌از تکمیل ورود به سیستم، هر سازوکار تأییدنشده قبلی برای ورود به سیستم از کاربر برداشته خواهد شد و همه جلسه‌های موجود نامعتبر خواهند شد. برای مثال، اگر فردی قبلاً حسابی تأییدنشده با همان ایمیل و گذرواژه ایجاد کرده باشد، گذرواژه کاربر برداشته می‌شود تا از ورود مجدد فردی که ادعای مالکیت کرده و آن حساب تأییدنشده را ایجاد کرده است با همان حساب جلوگیری شود.

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

‫Firebase Authentication از Firebase Hosting برای ارسال پیوند ایمیل به دستگاه همراه استفاده می‌کند. برای تکمیل ورود به سیستم با برنامه تلفن همراه، برنامه باید به‌گونه‌ای پیکربندی شود که پیوند برنامه ورودی را شناسایی کند، پیوند عمیق زیرین را تجزیه کند، و سپس ورود به سیستم را تکمیل کند. برای جزئیات بیشتر درباره نحوه انجام این کار، پیوندهای جهانی و دامنه‌های منسوب در iOS را بررسی کنید.

پیکربندی Firebase Hosting

‫Firebase Authentication هنگام ایجاد و ارسال پیوندی که قرار است در برنامه تلفن همراه باز شود از دامنه‌های Firebase Hosting استفاده می‌کند. دامنه Firebase Hosting پیش‌فرضی ازقبل برای شما پیکربندی شده است.

  1. پیکربندی Firebase Hosting دامنه:

    در کنسول Firebase، به میزبانی و بدون سرور > میزبانی بروید.

    • اگر می‌خواهید از دامنه پیش‌فرض برای پیوند ایمیلی که در برنامه‌های تلفن همراه باز می‌شود استفاده کنید، به سایت پیش‌فرضتان بروید و دامنه پیش‌فرض Hosting را یادداشت کنید. دامنه پیش‌فرض Hosting معمولاً به این شکل است: PROJECT_ID.firebaseapp.com.

      وقتی برنامه‌تان را برای رهگیری پیوند ورودی پیکربندی می‌کنید، به این مقدار نیاز خواهید داشت.

    • اگر می‌خواهید از دامنه سفارشی برای پیوند ایمیل استفاده کنید، می‌توانید دامنه سفارشی را در Firebase Hosting ثبت کنید و از آن برای دامنه پیوند استفاده کنید.

  2. پیکربندی برنامه‌های Apple:

    باید دامنه انتخابی را به‌عنوان دامنه منسوب برای پیوندهای برنامه پیکربندی کنید. برای راه‌اندازی مجوز در برنامه‌تان، در Xcode زبانه امضا و قابلیت‌ها هدف را باز کنید و دامنه‌های Firebase Hosting را از مرحله قبلی به قابلیت «دامنه‌های مرتبط» اضافه کنید. اگر از دامنه پیش‌فرض Firebase Hosting استفاده می‌کنید، این مقدار applinks:PROJECT_ID.firebaseapp.com خواهد بود.

    برای اطلاعات بیشتر، پشتیبانی از دامنه‌های منسوب در سایت اسناد Apple را ببینید.

پس‌از دریافت پیوند همان‌طور که در بالا توضیح داده شد، تأیید کنید که این پیوند برای درستی‌سنجی پیوند ایمیل است و ورود به سیستم را تکمیل کنید.

Swift

if Auth.auth().isSignIn(withEmailLink: link) {
        Auth.auth().signIn(withEmail: email, link: self.link) { user, error in
          // ...
        }
}

Objective-C

if ([[FIRAuth auth] isSignInWithEmailLink:link]) {
    [[FIRAuth auth] signInWithEmail:email
                               link:link
                         completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      // ...
    }];
}

برای آشنایی با نحوه مدیریت ورود به سیستم با پیوند ایمیل در برنامه Android، به راهنمای Android مراجعه کنید.

برای آشنایی با نحوه مدیریت ورود به سیستم با پیوند ایمیل در برنامه وب، به راهنمای وب مراجعه کنید.

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

تفاوت در نیمه دوم عملیات خواهد بود:

Swift

  let credential = EmailAuthCredential.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.link(with: credential) { authData, error in
    if (error) {
      // And error occurred during linking.
      return
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthProvider credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      linkWithCredential:credential
              completion:^(FIRAuthDataResult *_Nullable result,
                           NSError *_Nullable error) {
    if (error) {
      // And error occurred during linking.
      return;
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }];

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

Swift

  let credential = EmailAuthProvider.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in
    if (error) {
      // And error occurred during re-authentication.
      return
    }
    // The user was successfully re-authenticated.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthCredential credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      reauthenticateWithCredential:credential
                        completion:^(FIRAuthDataResult *_Nullable result,
                                     NSError *_Nullable error) {
    if (error) {
      // And error occurred during re-authentication
      return;
    }
    // The user was successfully re-authenticated.
  }];

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

پیش‌از Firebase Authentication iOS SDK v11.8.0، ویژگی ورود به سیستم با پیوند ایمیل برای باز کردن پیوندهای ورود به سیستم در برنامه صحیح به Firebase Dynamic Links متکی بود. این پیوندهای درستی‌سنجی منسوخ شده‌اند، زیرا Firebase Dynamic Links در تاریخ ۲۵ اوت ۲۰۲۵ تعطیل خواهد شد.

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

اگر پروژه خود را در تاریخ ۱۵ سپتامبر ۲۰۲۳ یا پس‌از آن ایجاد کرده‌اید، محافظت از شمارش ایمیل به‌طور پیش‌فرض فعال است. این ویژگی امنیت حساب‌های کاربری پروژه شما را بهبود می‌بخشد، اما روش fetchSignInMethodsForEmail() را که قبلاً برای پیاده‌سازی جریان‌های شناسه-اول توصیه می‌کردیم غیرفعال می‌کند.

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

برای کسب اطلاعات بیشتر، فعال یا غیرفعال کردن محافظت از شمارش ایمیل را ببینید.

مراحل بعدی

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

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

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

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

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

Swift

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

Objective-C

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

همچنین ممکن است بخواهید کد مدیریت خطا را برای طیف کامل خطاهای اصالت‌سنجی اضافه کنید. مدیریت خطاها را ببینید.