احراز هویت چند عاملی را به برنامه Flutter خود اضافه کنید

اگر به Firebase Authentication with Identity Platform ارتقا داده‌اید، می‌توانید احراز هویت چند مرحله‌ای از طریق پیامک را به برنامه Flutter خود اضافه کنید.

احراز هویت چند عاملی (MFA) امنیت برنامه شما را افزایش می‌دهد. در حالی که مهاجمان اغلب رمزهای عبور و حساب‌های کاربری شبکه‌های اجتماعی را به خطر می‌اندازند، رهگیری یک پیام متنی دشوارتر است.

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

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

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

  3. اندروید : اگر هنوز هش SHA-256 برنامه خود را در کنسول Firebase تنظیم نکرده‌اید، این کار را انجام دهید. برای اطلاعات بیشتر در مورد یافتن هش SHA-256 برنامه خود، به بخش «احراز هویت کلاینت» مراجعه کنید.

  4. iOS : در Xcode، اعلان‌های فوری را برای پروژه خود فعال کنید و مطمئن شوید که کلید احراز هویت APN شما با Firebase Cloud Messaging (FCM) پیکربندی شده است. علاوه بر این، باید حالت‌های پس‌زمینه را برای اعلان‌های از راه دور فعال کنید . برای مشاهده توضیح عمیق‌تر این مرحله، مستندات Firebase iOS Phone Auth را مشاهده کنید.

  5. وب : مطمئن شوید که دامنه برنامه‌های خود را در کنسول Firebase ، در زیر دامنه‌های تغییر مسیر OAuth اضافه کرده‌اید.

فعال کردن احراز هویت چند عاملی

  1. صفحه Authentication > Sign-in method را در کنسول Firebase باز کنید.

  2. در بخش پیشرفته ، تأیید هویت چند عاملی پیامکی را فعال کنید.

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

  3. اگر هنوز دامنه برنامه خود را مجاز نکرده‌اید، آن را به لیست مجاز در صفحه Authentication > Settings کنسول Firebase اضافه کنید.

انتخاب الگوی ثبت نام

شما می‌توانید انتخاب کنید که آیا برنامه شما به احراز هویت چند عاملی نیاز دارد یا خیر، و چگونه و چه زمانی کاربران خود را ثبت نام کنید. برخی از الگوهای رایج عبارتند از:

  • فاکتور دوم کاربر را به عنوان بخشی از ثبت نام ثبت کنید. اگر برنامه شما نیاز به احراز هویت چند عاملی برای همه کاربران دارد، از این روش استفاده کنید.

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

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

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

ثبت عامل دوم

برای ثبت یک عامل ثانویه جدید برای یک کاربر:

  1. کاربر را دوباره احراز هویت کنید.

  2. از کاربر بخواهید شماره تلفن خود را وارد کند.

  3. یک جلسه چند عاملی برای کاربر دریافت کنید:

    final multiFactorSession = await user.multiFactor.getSession();
    
  4. شماره تلفن را با یک جلسه چند عاملی و تماس‌های برگشتی خود تأیید کنید:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession: multiFactorSession,
      phoneNumber: phoneNumber,
      verificationCompleted: (_) {},
      verificationFailed: (_) {},
      codeSent: (String verificationId, int? resendToken) async {
        // The SMS verification code has been sent to the provided phone number.
        // ...
      },
      codeAutoRetrievalTimeout: (_) {},
    );
    
  5. پس از ارسال کد پیامکی، از کاربر بخواهید کد را تأیید کند:

    final credential = PhoneAuthProvider.credential(
      verificationId: verificationId,
      smsCode: smsCode,
    );
    
  6. تکمیل ثبت نام:

    await user.multiFactor.enroll(
      PhoneMultiFactorGenerator.getAssertion(
        credential,
      ),
    );
    

کد زیر مثال کاملی از ثبت یک عامل دوم را نشان می‌دهد:

  final session = await user.multiFactor.getSession();
  final auth = FirebaseAuth.instance;
  await auth.verifyPhoneNumber(
    multiFactorSession: session,
    phoneNumber: phoneController.text,
    verificationCompleted: (_) {},
    verificationFailed: (_) {},
    codeSent: (String verificationId, int? resendToken) async {
      // See `firebase_auth` example app for a method of retrieving user's sms code:
      // https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
      final smsCode = await getSmsCodeFromUser(context);

      if (smsCode != null) {
        // Create a PhoneAuthCredential with the code
        final credential = PhoneAuthProvider.credential(
          verificationId: verificationId,
          smsCode: smsCode,
        );

        try {
          await user.multiFactor.enroll(
            PhoneMultiFactorGenerator.getAssertion(
              credential,
            ),
          );
        } on FirebaseAuthException catch (e) {
          print(e.message);
        }
      }
    },
    codeAutoRetrievalTimeout: (_) {},
  );

تبریک! شما با موفقیت یک عامل احراز هویت دوم برای یک کاربر ثبت کردید.

ورود کاربران با استفاده از فاکتور دوم

برای ورود کاربر با تأیید دو مرحله‌ای پیامکی:

  1. کاربر را با اولین فاکتور خود وارد سیستم کنید، سپس خطای FirebaseAuthMultiFactorException را دریافت کنید. این خطا شامل یک resolver است که می‌توانید از آن برای دریافت فاکتورهای دوم ثبت شده کاربر استفاده کنید. همچنین شامل یک session اساسی است که تأیید می‌کند کاربر با اولین فاکتور خود با موفقیت احراز هویت شده است.

    برای مثال، اگر اولین فاکتور کاربر ایمیل و رمز عبور باشد:

    try {
      await _auth.signInWithEmailAndPassword(
          email: emailController.text,
          password: passwordController.text,
      );
      // User is not enrolled with a second factor and is successfully
      // signed in.
      // ...
    } on FirebaseAuthMultiFactorException catch (e) {
      // The user is a multi-factor user. Second factor challenge is required
      final resolver = e.resolver
      // ...
    }
    
  2. اگر کاربر چندین عامل ثانویه ثبت کرده است، از او بپرسید که از کدام یک استفاده کند:

    final session = e.resolver.session;
    
    final hint = e.resolver.hints[selectedHint];
    
  3. ارسال یک پیام تأیید به تلفن کاربر به همراه راهنما و جلسه چند عاملی:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession: session,
      multiFactorInfo: hint,
      verificationCompleted: (_) {},
      verificationFailed: (_) {},
      codeSent: (String verificationId, int? resendToken) async {
        // ...
      },
      codeAutoRetrievalTimeout: (_) {},
    );
    
  4. برای تکمیل احراز هویت ثانویه، تابع resolver.resolveSignIn() فراخوانی کنید:

    final smsCode = await getSmsCodeFromUser(context);
    if (smsCode != null) {
      // Create a PhoneAuthCredential with the code
      final credential = PhoneAuthProvider.credential(
        verificationId: verificationId,
        smsCode: smsCode,
      );
    
      try {
        await e.resolver.resolveSignIn(
          PhoneMultiFactorGenerator.getAssertion(credential)
        );
      } on FirebaseAuthException catch (e) {
        print(e.message);
      }
    }
    

کد زیر یک مثال کامل از ورود به سیستم چند عاملی کاربر را نشان می‌دهد:

try {
  await _auth.signInWithEmailAndPassword(
    email: emailController.text,
    password: passwordController.text,
  );
} on FirebaseAuthMultiFactorException catch (e) {
  setState(() {
    error = '${e.message}';
  });
  final firstHint = e.resolver.hints.first;
  if (firstHint is! PhoneMultiFactorInfo) {
    return;
  }
  await FirebaseAuth.instance.verifyPhoneNumber(
    multiFactorSession: e.resolver.session,
    multiFactorInfo: firstHint,
    verificationCompleted: (_) {},
    verificationFailed: (_) {},
    codeSent: (String verificationId, int? resendToken) async {
      // See `firebase_auth` example app for a method of retrieving user's sms code:
      // https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
      final smsCode = await getSmsCodeFromUser(context);

      if (smsCode != null) {
        // Create a PhoneAuthCredential with the code
        final credential = PhoneAuthProvider.credential(
          verificationId: verificationId,
          smsCode: smsCode,
        );

        try {
          await e.resolver.resolveSignIn(
            PhoneMultiFactorGenerator.getAssertion(
              credential,
            ),
          );
        } on FirebaseAuthException catch (e) {
          print(e.message);
        }
      }
    },
    codeAutoRetrievalTimeout: (_) {},
  );
} catch (e) {
  ...
}

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

قدم بعدی چیست؟