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

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

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

Başlamadan önce

  1. Çok öğeli 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ç her sağlayıcıda çok faktörlü kimlik doğrulama desteklenir.

  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, kötü niyetli kişilerin sahip olmadıkları bir e-posta adresiyle hizmete kaydolup ardından ikinci bir faktör ekleyerek gerçek sahibinin hesabına erişmesini engeller.

Çok öğeli kimlik doğrulamayı etkinleştirme

  1. Firebase konsolunda Güvenlik > Kimlik doğrulama'ya gidin.

  2. Oturum açma yöntemi sekmesindeki Gelişmiş bölümünde SMS ile Çok Öğeli Kimlik Doğrulama'yı etkinleştirin.

    Uygulamanızı test ederken kullanacağınız telefon numaralarını da girmeniz gerekir. Test telefon numaralarını kaydetmek isteğe bağlı olsa da geliştirme sırasında sıklık sınırlamasıyla karşılaşmamak için kesinlikle önerilir.

  3. Henüz yapmadıysanız uygulamanızın alanını yetkilendirin:

    1. Firebase konsolunda Güvenlik > Kimlik doğrulama > Ayarlar sekmesine gidin.

    2. Yetkili alanlar bölümünde Alan ekle'yi tıklayın ve alanınızı ekleyin.

Kayıt modeli seçme

Uygulamanızın çok öğeli kimlik doğrulaması gerektirip gerektirmediğini ve kullanıcılarınızı nasıl ve ne zaman kaydedeceğinizi seçebilirsiniz. Yaygın kullanılan bazı kalıplar şunlardır:

  • Kullanıcının ikinci faktörünü kayıt sırasında kaydedin. Uygulamanız tüm kullanıcılar için çok öğeli kimlik doğrulaması gerektiriyorsa bu yöntemi kullanın.

  • Kayıt sırasında ikinci bir faktör kaydetmek için atlanabilir bir seçenek sunun. Çok öğeli kimlik doğrulamayı zorunlu kılmak yerine teşvik etmek isteyen uygulamalar bu yaklaşımı tercih edebilir.

  • Kayıt ekranı yerine kullanıcının hesap veya profil yönetimi sayfasından ikinci bir faktör ekleme olanağı sunun. Bu sayede, kayıt sürecinde sorun yaşama ihtimali en aza indirilirken güvenliğe duyarlı kullanıcılar için çok öğeli kimlik doğrulama özelliği kullanılmaya devam edebilir.

  • Kullanıcı, güvenlik gereksinimleri yüksek olan özelliklere erişmek istediğinde ikinci bir faktörün kademeli olarak eklenmesini zorunlu kılın.

İkinci bir 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 öğeli oturum alma:

    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. Kaydolma işlemini tamamlayın:

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

Aşağıdaki kodda, ikinci faktör kaydetme işleminin tam bir örneği 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 etmenini başarıyla kaydettiniz.

Kullanıcıların ikinci bir faktörle oturum açmasını sağlama

Bir kullanıcının iki faktörlü SMS doğrulamasıyla oturum açmasını sağlamak için:

  1. Kullanıcının ilk faktörüyle oturum açmasını sağlayı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 öğeyle 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 şifre ise:

    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 etmeni varsa hangisini kullanmak istediğini sorun:

    final session = e.resolver.session;
    
    final hint = e.resolver.hints[selectedHint];
    
  3. İpucu ve çok öğeli kimlik doğrulama oturumu ile birlikte kullanıcının telefonuna bir doğrulama mesajı 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ğrulamayı kullanarak bir kullanıcının oturumunu başarıyla açtınız.

Sırada ne var?