Flutter uygulamanıza çok öğeli kimlik doğrulaması ekleme

Identity Platform ile Firebase Authentication'e yükselttiyseniz Flutter uygulamanıza SMS çok faktörlü kimlik doğrulaması ekleyebilirsiniz.

Çok faktörlü kimlik doğrulaması (MFA), uygulamanızın güvenliğini artırır. Saldırganlar genellikle şifreler ve sosyal hesapların güvenliğini ihlal etse de kısa mesajları ele geçirmek daha zordur.

Başlamadan önce

  1. Çok faktörlü kimlik doğrulamayı destekleyen en az bir sağlayıcıyı etkinleştirin. Telefonla kimlik doğrulama, anonim kimlik doğrulama ve Apple Game Center hariç tüm sağlayıcılar MFA'yı destekler.

  2. Uygulamanızın kullanıcı e-postalarını doğruladığından emin olun. Çok faktörlü kimlik doğrulama için e-posta doğrulaması gerekir. Bu sayede, kötü niyetli kişilerin bir hizmete sahip olmadıkları bir e-posta adresiyle kaydolup ikinci bir faktör ekleyerek gerçek sahibin erişimini engellemesi önlenir.

  3. Android: Uygulamanızın SHA-256 karmasını Firebase konsolunda ayarlamadıysanız bunu yapın. Uygulamanızın SHA-256 karmasını bulma hakkında bilgi edinmek için İstemcinizin Kimliğini Doğrulama başlıklı makaleyi inceleyin.

  4. iOS: Xcode'da projeniz için push bildirimleri etkinleştirin ve APNs kimlik doğrulama anahtarınızın Firebase Cloud Messaging (FCM) ile yapılandırıldığından emin olun. Ayrıca, uzaktan bildirimler için arka plan modlarını etkinleştirmeniz gerekir. Bu adımın ayrıntılı açıklamasını görmek için Firebase iOS Telefon Kimlik Doğrulaması belgelerini inceleyin.

  5. Web: Uygulamanızın alanını Firebase Konsolu'ndaki OAuth yönlendirme alanları bölümüne eklediğinizden emin olun.

Çok faktörlü kimlik doğrulamayı etkinleştirme

  1. Firebase konsolunun Kimlik doğrulama > Oturum açma yöntemi sayfasını açın.

  2. Gelişmiş bölümünde SMS ile Çok Öğeli Kimlik Doğrulaması'nı etkinleştirin.

    Ayrıca, uygulamanızı test ederken kullanacağınız telefon numaralarını da girmeniz gerekir. İsteğe bağlı olsa da geliştirme sırasında akış kısıtlamasını önlemek için test telefon numaralarını kaydetmeniz önemle tavsiye edilir.

  3. Uygulamanızın alanını henüz yetkilendirmediyseniz Firebase konsolunun Kimlik Doğrulama > Ayarlar sayfasında izin verilenler listesine ekleyin.

Kayıt modeli seçme

Uygulamanızda çok faktörlü kimlik doğrulamasının gerekli olup olmadığını, kullanıcılarınızı nasıl ve ne zaman kaydedeceğinizi seçebilirsiniz. Sık karşılaşılan bazı kalıplar şunlardır:

  • Kayıt işleminin bir parçası olarak kullanıcının ikinci faktörünü kaydedin. Uygulamanız tüm kullanıcılar için çok faktörlü kimlik doğrulaması gerektiriyorsa bu yöntemi kullanın.

  • Kayıt sırasında ikinci bir faktör kaydetme seçeneği sunun. Çok faktörlü kimlik doğrulamayı teşvik etmek ancak zorunlu tutmak isteyen uygulamalar bu yaklaşımı tercih edebilir.

  • Kayıt ekranı yerine kullanıcının hesabından veya profil yönetimi sayfasından ikinci bir faktör ekleme olanağı sunun. Bu sayede, kayıt işlemi sırasındaki zorlukları en aza indirirken güvenlik konusunda hassas kullanıcılar için çok faktörlü kimlik doğrulamayı kullanmaya devam edebilirsiniz.

  • Kullanıcı, daha yüksek güvenlik şartlarına sahip özelliklere erişmek istediğinde kademeli olarak ikinci bir faktör eklemesini zorunlu kılın.

İkinci faktör kaydetme

Bir kullanıcı için yeni bir ikincil faktör kaydetmek üzere:

  1. Kullanıcının kimliğini yeniden doğrulayın.

  2. Kullanıcıdan telefon numarasını girmesini isteyin.

  3. Kullanıcı için çok faktörlü oturum alın:

    final multiFactorSession = await user.multiFactor.getSession();
    
  4. Telefon numarasını çok faktörlü oturum ve geri aramalarınızla doğrulayın:

    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. SMS kodu gönderildikten sonra kullanıcıdan kodu doğrulamasını isteyin:

    final credential = PhoneAuthProvider.credential(
      verificationId: verificationId,
      smsCode: smsCode,
    );
    
  6. Kayıt işlemini tamamlayın:

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

Aşağıdaki kodda, ikinci bir faktör kaydetmeyle ilgili eksiksiz bir örnek gösterilmektedir:

  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: (_) {},
  );

Tebrikler! Bir kullanıcı için ikinci bir kimlik doğrulama faktörü başarıyla kaydettiniz.

Kullanıcıların oturumunu ikinci bir faktörle açma

İki faktörlü SMS doğrulamasıyla kullanıcının oturumunu açmak için:

  1. Kullanıcıyı ilk faktörüyle oturum açtırın, ardından FirebaseAuthMultiFactorException istisnasını yakalayın. Bu hata, kullanıcının kayıtlı ikinci faktörlerini almak için kullanabileceğiniz bir çözümleyici içerir. Ayrıca, kullanıcının birinci faktörüyle başarılı bir şekilde kimlik doğruladığını kanıtlayan temel bir oturum da içerir.

    Örneğin, kullanıcının ilk faktörü e-posta ve şifreyse:

    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. Kullanıcının kayıtlı birden fazla ikincil faktörü varsa hangisini kullanacağını sorun:

    final session = e.resolver.session;
    
    final hint = e.resolver.hints[selectedHint];
    
  3. İpucu ve çok faktörlü oturumu içeren bir doğrulama mesajını kullanıcının telefonuna gönderin:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession: session,
      multiFactorInfo: hint,
      verificationCompleted: (_) {},
      verificationFailed: (_) {},
      codeSent: (String verificationId, int? resendToken) async {
        // ...
      },
      codeAutoRetrievalTimeout: (_) {},
    );
    
  4. İkincil kimlik doğrulamayı tamamlamak için resolver.resolveSignIn() numaralı telefonu arayın:

    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);
      }
    }
    

Aşağıdaki kod, çok faktörlü bir kullanıcının oturum açmasıyla ilgili eksiksiz bir örnek gösterir:

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

Tebrikler! Çok öğeli kimlik doğrulamasını kullanarak bir kullanıcının oturumunu başarıyla açtınız.

Sırada ne var?