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

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

ورود از طریق ایمیل مزایای زیادی دارد:

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

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

  1. اگر قبلاً این کار را نکرده‌اید، مراحل راهنمای شروع کار را دنبال کنید.

  2. ورود به سیستم Email Link را برای پروژه Firebase خود فعال کنید.

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

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

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

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

    • url : پیوند عمیق برای جاسازی و هر حالت اضافی که باید همراه آن منتقل شود. دامنه پیوند باید در لیست دامنه های مجاز Firebase Console قرار گیرد که با رفتن به برگه روش ورود (Authentication -> Sign-in) می توانید آن را پیدا کنید. اگر برنامه روی دستگاهش نصب نشده باشد و برنامه نصب نشود، پیوند کاربر را به این URL هدایت می‌کند.

    • androidPackageName و IOSBundleId : برنامه‌هایی که هنگام باز شدن پیوند ورود به سیستم در دستگاه Android یا iOS استفاده می‌شوند. درباره نحوه پیکربندی Firebase Dynamic Links برای باز کردن پیوندهای اقدام ایمیل از طریق برنامه های تلفن همراه بیشتر بیاموزید.

    • handleCodeInApp : روی true تنظیم کنید. عملیات ورود به سیستم برخلاف سایر اقدامات ایمیل خارج از باند (بازنشانی رمز عبور و تأیید ایمیل) باید همیشه در برنامه تکمیل شود. این به این دلیل است که در پایان جریان، انتظار می رود کاربر وارد سیستم شود و وضعیت Auth او در برنامه باقی بماند.

    • dynamicLinkDomain : هنگامی که چندین دامنه پیوند پویا سفارشی برای یک پروژه تعریف می شود، مشخص کنید که زمانی که پیوند از طریق یک برنامه تلفن همراه مشخص شده باز می شود، از کدام یک استفاده شود (به عنوان مثال، example.page.link ). در غیر این صورت اولین دامنه به طور خودکار انتخاب می شود.

    var acs = ActionCodeSettings(
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true
        handleCodeInApp: true,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  2. از کاربر ایمیل خود را بخواهید.

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

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

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

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

می‌توانید این جریان را برای کاربرانی که پیوند ورود به سیستم را در همان دستگاهی که پیوند را درخواست می‌کنند باز می‌کنند، با ذخیره آدرس ایمیل آنها به صورت محلی - به عنوان مثال با استفاده از SharedPreferences - هنگام ارسال ایمیل ورود به سیستم، ساده کنید. سپس، از این آدرس برای تکمیل جریان استفاده کنید. ایمیل کاربر را در پارامترهای URL تغییر مسیر ندهید و دوباره از آن استفاده کنید زیرا ممکن است تزریق جلسه را فعال کند.

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

همچنین مطمئن شوید که از URL HTTPS در تولید استفاده می کنید تا از رهگیری بالقوه پیوند شما توسط سرورهای واسطه جلوگیری کنید.

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

  1. برنامه خود را برای دریافت پیوندهای پویا در فلاتر در راهنما تنظیم کنید.

  2. در مدیریت پیوند خود، بررسی کنید که آیا پیوند برای احراز هویت پیوند ایمیل است یا خیر و اگر چنین است، فرآیند ورود به سیستم را کامل کنید.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

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

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

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

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

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

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

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

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

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

مراحل بعدی

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

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

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

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

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

await FirebaseAuth.instance.signOut();