أضف مصادقة متعددة العوامل إلى تطبيق Flutter الخاص بك

إذا قمت بالترقية إلى مصادقة Firebase باستخدام Identity Platform، فيمكنك إضافة مصادقة متعددة العوامل عبر الرسائل النصية القصيرة إلى تطبيق Flutter.

تعمل المصادقة متعددة العوامل (MFA) على زيادة أمان تطبيقك. في حين أن المهاجمين غالبًا ما يخترقون كلمات المرور والحسابات الاجتماعية، إلا أن اعتراض الرسائل النصية يكون أكثر صعوبة.

قبل ان تبدأ

  1. تمكين موفر واحد على الأقل يدعم المصادقة متعددة العوامل. يدعم كل مزود خدمة MFA، باستثناء مصادقة الهاتف والمصادقة المجهولة وApple Game Center.

  2. تأكد من أن تطبيقك يتحقق من رسائل البريد الإلكتروني للمستخدم. يتطلب MFA التحقق من البريد الإلكتروني. ويمنع هذا الجهات الفاعلة الخبيثة من التسجيل في خدمة باستخدام بريد إلكتروني لا يملكونه، ثم إغلاق المالك الحقيقي عن طريق إضافة عامل ثانٍ.

  3. Android : إذا لم تكن قد قمت بالفعل بتعيين تجزئة SHA-256 لتطبيقك في وحدة تحكم Firebase ، فقم بذلك. راجع مصادقة عميلك للحصول على معلومات حول العثور على تجزئة SHA-256 لتطبيقك.

  4. iOS : في Xcode، قم بتمكين الإشعارات المباشرة لمشروعك وتأكد من تكوين مفتاح مصادقة APNs الخاص بك باستخدام Firebase Cloud Messaging (FCM) . بالإضافة إلى ذلك، يجب عليك تمكين أوضاع الخلفية للإشعارات عن بعد. لعرض شرح متعمق لهذه الخطوة، راجع وثائق Firebase iOS Phone Auth .

  5. الويب : تأكد من إضافة مجال التطبيقات الخاص بك على وحدة تحكم Firebase ، ضمن مجالات إعادة توجيه OAuth .

تمكين المصادقة متعددة العوامل

  1. افتح صفحة المصادقة > طريقة تسجيل الدخول لوحدة تحكم Firebase.

  2. في القسم المتقدم ، قم بتمكين المصادقة متعددة العوامل عبر الرسائل القصيرة .

    يجب عليك أيضًا إدخال أرقام الهواتف التي ستختبر تطبيقك بها. على الرغم من أن تسجيل أرقام هواتف الاختبار أمر اختياري، إلا أنه يوصى بشدة لتجنب التقييد أثناء التطوير.

  3. إذا لم تكن قد سمحت بالفعل بنطاق تطبيقك، فأضفه إلى قائمة السماح في صفحة المصادقة > الإعدادات في وحدة تحكم 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/master/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 . يحتوي هذا الخطأ على محلل يمكنك استخدامه للحصول على العوامل الثانية المسجلة للمستخدم. ويحتوي أيضًا على جلسة أساسية تثبت نجاح مصادقة المستخدم باستخدام العامل الأول.

    على سبيل المثال، إذا كان العامل الأول للمستخدم هو البريد الإلكتروني وكلمة المرور:

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

تهانينا! لقد قمت بتسجيل دخول المستخدم بنجاح باستخدام المصادقة متعددة العوامل.

ماذا بعد