با Firebase با استفاده از Email Link در پلتفرم‌های Apple احراز هویت

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

There are numerous benefits to signing in by email:

  • ثبت نام و ورود به سیستم با اصطکاک کم.
  • Lower risk of password reuse across applications, which can undermine security of even well-selected passwords.
  • The ability to authenticate a user while also verifying that the user is the legitimate owner of an email address.
  • یک کاربر برای ورود فقط به یک حساب ایمیل قابل دسترسی نیاز دارد. مالکیت شماره تلفن یا حساب رسانه اجتماعی مورد نیاز نیست.
  • یک کاربر می تواند بدون نیاز به ارائه (یا به خاطر سپردن) رمز عبور، به طور ایمن وارد سیستم شود، که ممکن است در یک دستگاه تلفن همراه دست و پا گیر باشد.
  • An existing user who previously signed in with an email identifier (password or federated) can be upgraded to sign in with just the email. For example, a user who has forgotten their password can still sign in without needing to reset their password.

قبل از شروع

برای نصب و مدیریت وابستگی های Firebase از Swift Package Manager استفاده کنید.

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

To sign in users by email link, you must first enable the Email provider and Email link sign-in method for your Firebase project:

  1. در کنسول Firebase ، بخش Auth را باز کنید.
  2. در برگه روش ورود به سیستم ، ارائه دهنده ایمیل/گذرواژه را فعال کنید. توجه داشته باشید که ورود ایمیل/رمز عبور برای استفاده از ورود به سیستم پیوند ایمیل باید فعال باشد.
  3. در همان بخش، روش ورود به سیستم پیوند ایمیل (ورود بدون رمز عبور) را فعال کنید.
  4. روی ذخیره کلیک کنید.

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

  1. Construct the ActionCodeSettings object, which provides Firebase with instructions on how to construct the email link. فیلدهای زیر را تنظیم کنید:

    • url : پیوند عمیق برای جاسازی و هر حالت اضافی که باید همراه آن منتقل شود. دامنه پیوند باید در لیست دامنه های مجاز Firebase Console قرار گیرد که با رفتن به برگه روش ورود (Authentication -> Sign-in) می توانید آن را پیدا کنید.
    • iOSBundleID و androidPackageName : Firebase Authentication کمک می‌کند تا تعیین کند آیا باید یک پیوند فقط وب یا تلفن همراه ایجاد کند که در دستگاه Android یا Apple باز شود.
    • handleCodeInApp : روی true تنظیم کنید. عملیات ورود به سیستم برخلاف سایر اقدامات ایمیل خارج از باند (بازنشانی رمز عبور و تأیید ایمیل) باید همیشه در برنامه تکمیل شود. این به این دلیل است که در پایان جریان، انتظار می رود کاربر وارد سیستم شود و وضعیت Auth او در برنامه باقی بماند.
    • linkDomain : زمانی که دامنه‌های پیوند Hosting سفارشی برای یک پروژه تعریف می‌شوند، مشخص کنید که در هنگام باز شدن پیوند توسط یک برنامه تلفن همراه مشخص، از کدام یک استفاده کنید. در غیر این صورت دامنه پیش فرض به طور خودکار انتخاب می شود (به عنوان مثال، PROJECT_ID .firebaseapp.com ).
    • dynamicLinkDomain : منسوخ شده است. این پارامتر را مشخص نکنید.

    سویفت

    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")

    هدف-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 ، به بخش Passing State in Email Actions مراجعه کنید.

  2. از کاربر ایمیل خود را بخواهید.

  3. پیوند احراز هویت را به ایمیل کاربر ارسال کنید و ایمیل کاربر را در صورتی که کاربر ورود به ایمیل را در همان دستگاه کامل کند، ذخیره کنید.

    سویفت

    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")
        // ...
    }

    هدف-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 نیاز دارد که آدرس ایمیل کاربر هنگام تکمیل جریان ورود به سیستم ارائه شود. برای موفقیت در ورود به سیستم، این آدرس ایمیل باید با آدرسی که پیوند ورود به سیستم در ابتدا به آن ارسال شده است مطابقت داشته باشد.

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

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

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

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

Firebase Hosting پیکربندی کنید

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

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

    در کنسول Firebase ، بخش Hosting را باز کنید.

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

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

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

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

    شما باید دامنه انتخابی را به عنوان یک دامنه مرتبط برای پیوندهای برنامه پیکربندی کنید. برای تنظیم حق در برنامه خود، برگه Signing & Capabilities هدف را در Xcode باز کنید و دامنه های میزبانی Firebase را از مرحله قبل به قابلیت Associated Domains اضافه کنید. اگر از دامنه Firebase Hosting پیش فرض استفاده کنید، این خواهد بود applinks: PROJECT_ID .firebaseapp.com .

    برای اطلاعات بیشتر به پشتیبانی از دامنه های مرتبط در سایت اسناد اپل مراجعه کنید.

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

سویفت

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

هدف-C

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

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

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

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

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

سویفت

  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.
  }

هدف-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.
  }];

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

سویفت

  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.
  }

هدف-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.
  }];

با این حال، از آنجایی که جریان ممکن است به دستگاه دیگری ختم شود که کاربر اصلی در آن وارد نشده است، این جریان ممکن است تکمیل نشود. در این صورت می توان خطایی به کاربر نشان داد تا مجبور شود لینک را در همان دستگاه باز کند. Some state can be passed in the link to provide information on the type of operation and the user uid.

قبل از Firebase Authentication iOS SDK v11.8.0، ویژگی ورود پیوند ایمیل به Firebase Dynamic Links برای باز کردن پیوندهای ورود به سیستم در برنامه صحیح متکی بود. These verification links are deprecated, as Firebase Dynamic Links will shut down on August 25, 2025 .

If your app uses the old style links, you should migrate your app to the new Firebase Hosting based system.

If you created your project on or after September 15, 2023, email enumeration protection is enabled by default. این ویژگی امنیت حساب‌های کاربری پروژه شما را بهبود می‌بخشد، اما متد fetchSignInMethodsForEmail() را غیرفعال می‌کند، که قبلاً برای پیاده‌سازی جریان‌های شناسه اول توصیه می‌کردیم.

Although you can disable email enumeration protection for your project, we recommend against doing so.

To learn more, see Enable or disable email enumeration protection .

مراحل بعدی

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

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

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

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

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

سویفت

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

هدف-C

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

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