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

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

مزایای بی‌شماری برای ورود از طریق ایمیل وجود دارد:

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

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

برای نصب و مدیریت وابستگی‌های 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 خود فعال کنید:

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

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

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

    • url : لینک عمیق برای جاسازی و هر وضعیت اضافی که باید منتقل شود. دامنه‌ی لینک باید در فهرست دامنه‌های مجاز کنسول Firebase در لیست سفید قرار داشته باشد، که می‌توانید با رفتن به تب روش ورود (Authentication -> Sign-in method) آن را پیدا کنید.
    • iOSBundleID و androidPackageName : به Firebase Authentication کمک می‌کند تا تعیین کند که آیا باید یک لینک فقط وب یا موبایل ایجاد کند که روی دستگاه اندروید یا اپل باز می‌شود.
    • handleCodeInApp : روی true تنظیم شده است. عملیات ورود به سیستم برخلاف سایر اقدامات ایمیل خارج از باند (تنظیم مجدد رمز عبور و تأیید ایمیل) باید همیشه در برنامه انجام شود. دلیل این امر این است که در پایان جریان، انتظار می‌رود کاربر وارد سیستم شده باشد و وضعیت احراز هویت او در برنامه باقی بماند.
    • 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")

    هدف-سی

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

    سویفت

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

    هدف-سی

    [[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 Hosting را از مرحله قبل به قابلیت 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
          // ...
        }
}

هدف-سی

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

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

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

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

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

سویفت

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

هدف-سی

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

هدف-سی

  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 نسخه ۱۱.۸.۰، ویژگی ورود از طریق لینک ایمیل برای باز کردن لینک‌های ورود در برنامه صحیح به Firebase Dynamic Links متکی بود. این لینک‌های تأیید اعتبار منسوخ شده‌اند، زیرا Firebase Dynamic Links در ۲۵ آگوست ۲۰۲۵ غیرفعال خواهد شد.

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

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

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

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

مراحل بعدی

پس از اینکه کاربر برای اولین بار وارد سیستم می‌شود، یک حساب کاربری جدید ایجاد می‌شود و به اطلاعات احراز هویت - یعنی نام کاربری و رمز عبور، شماره تلفن یا اطلاعات ارائه دهنده مجوز - که کاربر با آن وارد سیستم شده است، پیوند داده می‌شود. این حساب جدید به عنوان بخشی از پروژه 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;
}

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