Autentikasi dengan Ponsel

Dengan autentikasi ponsel, pengguna dapat login ke Firebase menggunakan ponselnya sebagai pengautentikasi. Pesan SMS dikirim kepada pengguna (menggunakan nomor telepon yang diberikan) yang berisi kode unik. Setelah kode diotorisasi, pengguna dapat login ke Firebase.

Nomor telepon yang diberikan pengguna akhir untuk autentikasi akan dikirim dan disimpan oleh Google untuk meningkatkan kualitas pencegahan spam dan penyalahgunaan di seluruh layanan Google, termasuk, tetapi tidak terbatas pada Firebase. Developer harus memastikan bahwa mereka memiliki izin pengguna akhir yang sesuai sebelum menggunakan layanan login dengan nomor telepon dari Firebase Authentication.

Tidak semua negara mendukung Autentikasi dengan Ponsel pada Firebase. Lihat FAQ untuk mengetahui informasi selengkapnya.

Penyiapan

Sebelum memulai Autentikasi dengan Ponsel, pastikan Anda telah mengikuti langkah-langkah berikut:

  1. Aktifkan Ponsel sebagai Metode login di Firebase console.
  2. Android: Setel hash SHA-1 aplikasi Anda di Firebase console jika belum melakukannya. Baca Mengautentikasi Klien untuk mengetahui informasi tentang cara menemukan hash SHA-1 aplikasi.
  3. iOS: Di Xcode, aktifkan notifikasi push untuk project Anda & pastikan kunci autentikasi APNs Anda dikonfigurasi dengan Firebase Cloud Messaging (FCM). Selain itu, Anda harus mengaktifkan mode latar belakang untuk notifikasi jarak jauh. Untuk melihat penjelasan mendalam tentang langkah ini, lihat dokumentasi Autentikasi Ponsel iOS Firebase.
  4. Web: Pastikan Anda telah menambahkan domain aplikasi di Firebase console di bagian OAuth redirect domains.

Catatan; Login dengan nomor telepon hanya tersedia untuk penggunaan di web dan perangkat sungguhan. Untuk menguji alur autentikasi pada emulator perangkat, harap lihat Pengujian.

Penggunaan

Firebase Authentication SDK untuk Flutter menyediakan 2 cara terpisah untuk memungkinkan pengguna login dengan nomor telepon. Platform native (misalnya Android & iOS) menyediakan fungsi yang berbeda untuk memvalidasi nomor telepon dibandingkan dengan web. Oleh karena itu, ada dua metode berbeda untuk setiap platform:

  • Platform Native: verifyPhoneNumber.
  • Platform Web: signInWithPhoneNumber.

Native: verifyPhoneNumber

Di platform native, nomor telepon pengguna harus diverifikasi terlebih dahulu, lalu pengguna dapat login atau menautkan akunnya dengan PhoneAuthCredential.

Pertama, Anda harus meminta nomor telepon pengguna. Setelah diberikan, panggil metode verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Ada 4 callback terpisah yang harus Anda tangani, masing-masing akan menentukan cara Anda memperbarui UI aplikasi:

  1. verificationCompleted: Penanganan otomatis kode SMS di perangkat Android.
  2. verificationFailed: Menangani peristiwa kegagalan seperti nomor telepon yang tidak valid atau apakah kuota SMS telah terlampaui.
  3. codeSent: Menangani saat kode telah dikirim ke perangkat dari Firebase, yang digunakan untuk meminta pengguna memasukkan kode.
  4. codeAutoRetrievalTimeout: Menangani waktu tunggu habis saat penanganan kode SMS otomatis gagal.

verificationCompleted

Pengendali ini hanya akan dipanggil di perangkat Android yang mendukung resolusi kode SMS otomatis.

Saat kode SMS dikirim ke perangkat, Android akan otomatis memverifikasi kode SMS tanpa mengharuskan pengguna memasukkan kode secara manual. Jika peristiwa ini terjadi, PhoneAuthCredential otomatis disediakan yang dapat digunakan untuk login dengan atau menautkan nomor telepon pengguna.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

Jika Firebase menampilkan error, misalnya untuk nomor telepon yang salah atau jika kuota SMS untuk project telah terlampaui, FirebaseAuthException akan dikirim ke pengendali ini. Dalam hal ini, Anda akan memberi tahu pengguna bahwa ada yang salah, bergantung pada kode error.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

Saat Firebase mengirim kode SMS ke perangkat, pengendali ini akan dipicu dengan verificationId dan resendToken (resendToken hanya didukung di perangkat Android, perangkat iOS akan selalu menampilkan nilai null).

Setelah dipicu, sekarang adalah waktu yang tepat untuk memperbarui UI aplikasi Anda untuk meminta pengguna memasukkan kode SMS yang mereka harapkan. Setelah kode SMS dimasukkan, Anda dapat menggabungkan ID verifikasi dengan kode SMS untuk membuat PhoneAuthCredential baru:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

Secara default, Firebase tidak akan mengirim ulang pesan SMS baru jika pesan tersebut baru saja dikirim. Namun, Anda dapat mengganti perilaku ini dengan memanggil kembali metode verifyPhoneNumber menggunakan token kirim ulang ke argumen forceResendingToken. Jika berhasil, pesan SMS akan dikirim ulang.

codeAutoRetrievalTimeout

Pada perangkat Android yang mendukung resolusi kode SMS otomatis, pengendali ini akan dipanggil jika perangkat belum me-resolve pesan SMS secara otomatis dalam jangka waktu tertentu. Setelah jangka waktu berlalu, perangkat tidak akan lagi mencoba me-resolve pesan masuk.

Secara default, perangkat menunggu selama 30 detik, tetapi hal ini dapat disesuaikan dengan argumen timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Web: signInWithPhoneNumber

Pada platform web, pengguna dapat login dengan mengonfirmasi bahwa mereka memiliki akses ke ponsel dengan memasukkan kode SMS yang dikirim ke nomor telepon yang diberikan. Untuk keamanan tambahan dan pencegahan spam, pengguna diminta untuk membuktikan bahwa mereka adalah manusia dengan menyelesaikan widget Google reCAPTCHA. Setelah dikonfirmasi, kode SMS akan dikirimkan.

Firebase Authentication SDK untuk Flutter akan mengelola widget reCAPTCHA secara default, namun memberikan kontrol atas cara widget ini ditampilkan dan dikonfigurasi jika diperlukan. Untuk memulai, panggil metode signInWithPhoneNumber dengan nomor telepon tersebut.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

Memanggil metode ini akan terlebih dahulu memicu widget reCAPTCHA untuk ditampilkan. Pengguna harus menyelesaikan pengujian sebelum kode SMS dikirim. Setelah selesai, Anda dapat memproses login pengguna dengan memberikan kode SMS ke metode confirm pada respons ConfirmationResult yang di-resolve:

UserCredential userCredential = await confirmationResult.confirm('123456');

Seperti alur login lainnya, proses login yang berhasil akan memicu pemroses status autentikasi yang Anda ikuti di aplikasi.

Konfigurasi reCAPTCHA

Widget reCAPTCHA adalah alur yang terkelola sepenuhnya yang memberikan keamanan pada aplikasi web Anda.

Argumen kedua signInWithPhoneNumber menerima instance RecaptchaVerifier opsional yang dapat digunakan untuk mengelola widget. Secara default, widget akan dirender sebagai widget yang tidak terlihat saat alur login dipicu. Widget "tidak terlihat" akan muncul sebagai modal halaman penuh di atas aplikasi Anda.

Namun, ada kemungkinan untuk menampilkan widget inline yang harus ditekan pengguna secara eksplisit untuk memverifikasi dirinya sendiri.

Untuk menambahkan widget inline, tentukan ID elemen DOM ke argumen container dari instance RecaptchaVerifier. Elemen tersebut harus ada dan kosong. Jika tidak, error akan ditampilkan. Jika tidak ada argumen container yang diberikan, widget akan dirender sebagai "tidak terlihat".

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

Anda memiliki pilihan untuk mengubah ukuran dan tema dengan menyesuaikan argumen size dan theme seperti yang ditunjukkan di atas.

Ada juga kemungkinan untuk memproses peristiwa, seperti apakah reCAPTCHA telah diselesaikan oleh pengguna atau tidak, apakah reCAPTCHA telah berakhir atau ada error yang ditampilkan:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Pengujian

Firebase menyediakan dukungan untuk menguji nomor telepon secara lokal:

  1. Di Firebase Console, pilih penyedia autentikasi "Phone" dan klik dropdown "Phone numbers for testing".
  2. Masukkan nomor telepon baru (misalnya +44 7444 555666) dan kode pengujian (misalnya 123456).

Jika memberikan nomor telepon uji coba ke metode verifyPhoneNumber atau signInWithPhoneNumber, tidak akan ada SMS yang benar-benar dikirim. Sebagai gantinya, Anda dapat memberikan kode pengujian secara langsung ke PhoneAuthProvider atau dengan pengendali hasil konfirmasi signInWithPhoneNumber.