Buka konsol

Mengautentikasi dengan Firebase Menggunakan Link Email di iOS

Anda dapat menggunakan Firebase Authentication untuk membuat pengguna login dengan mengirimkan email yang berisi link, yang dapat ia klik untuk login. Dalam prosesnya, alamat email pengguna juga akan diverifikasi.

Ada banyak manfaat login dengan email:

  • Proses pendaftaran dan login lebih lancar.
  • Risiko penggunaan ulang sandi pada banyak aplikasi lebih rendah. Penggunaan sandi yang sama dapat mengurangi keamanan, sekalipun sandi sudah dipilih dengan baik.
  • Dapat mengautentikasi pengguna, sekaligus memverifkasi bahwa pengguna adalah pemilik sah alamat email.
  • Pengguna hanya memerlukan akun email yang dapat diakses untuk login. Tidak diperlukan kepemilikan akun media sosial atau nomor telepon.
  • Pengguna dapat login dengan aman tanpa perlu memasukkan (atau mengingat) sandi, yang bisa merepotkan pada perangkat seluler.
  • Pengguna yang sudah ada dan sebelumnya login dengan ID email (sandi atau penyedia identitas gabungan) dapat di-upgrade untuk login dengan email saja. Misalnya, pengguna yang lupa sandi masih dapat login tanpa perlu menyetel ulang sandinya.

Sebelum Anda memulai

  1. Tambahkan Firebase ke project iOS Anda. Sertakan pod berikut di Podfile:
    pod 'Firebase/Auth'
  2. Jika Anda belum menghubungkan aplikasi ke project Firebase, lakukanlah dari Firebase console.

Untuk membuat pengguna login melalui link email, pertama-tama Anda harus mengaktifkan metode login dengan Link email dan Penyedia email untuk project Firebase Anda:

  1. Di Firebase console, buka bagian Auth.
  2. Pada tab Metode login, aktifkan penyedia Email/Sandi. Perlu diketahui bahwa login dengan email/sandi harus diaktifkan untuk menggunakan metode login dengan link email.
  3. Di bagian yang sama, aktifkan metode login dengan Link email (login tanpa sandi).
  4. Klik Simpan.

Untuk memulai alur autentikasi, tampilkan antarmuka yang akan meminta pengguna memberikan alamat email, lalu panggil sendSignInLinkToEmail:actionCodeSettings:completion: untuk meminta Firebase mengirimkan link autentikasi ke email pengguna.

  1. Buat objek ActionCodeSettings yang akan memberi Firebase petunjuk mengenai cara membuat link email. Tetapkan kolom berikut:

    • url: Deep link yang akan disematkan dan semua status tambahan yang akan diteruskan. Domain link harus diizinkan dalam daftar domain resmi Firebase Console, yang dapat ditemukan dengan membuka tab Metode login (Authentication -> Metode login).
    • iOSBundleID dan androidPackageName: Aplikasi yang akan digunakan saat link login dibuka di perangkat Android atau iOS. Pelajari lebih lanjut tentang cara mengonfigurasi Firebase Dynamic Links untuk membuka link tindakan email melalui aplikasi seluler.
    • handleCodeInApp: Tetapkan ke true. Operasi login harus selalu diselesaikan di aplikasi, tidak seperti tindakan email out of band yang lain (penyetelan ulang sandi dan verifikasi email). Hal ini perlu dilakukan karena di akhir proses, pengguna diharapkan sudah login dan status Auth-nya tetap tersimpan di dalam aplikasi.
    • dynamicLinkDomain: Ketika beberapa domain link dinamis kustom ditetapkan untuk suatu project, tentukan domain yang akan digunakan jika link dibuka melalui aplikasi seluler tertentu (misalnya, example.page.link). Jika tidak, domain pertama akan dipilih secara otomatis.

    Swift

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.url = URL(string: "https://www.example.com")
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
    actionCodeSettings.setAndroidPackageName("com.example.android",
                                             installIfNotAvailable: false, minimumVersion: "12")
    

    Objective-C

    FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
    [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]];
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = YES;
    [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]];
    [actionCodeSettings setAndroidPackageName:@"com.example.android"
                        installIfNotAvailable:NO
                               minimumVersion:@"12"];
    

    Untuk mempelajari ActionCodeSettings lebih lanjut, baca bagian Meneruskan Status dalam Tindakan Email.

  2. Minta pengguna memberikan alamat emailnya.

  3. Kirim link autentikasi ke email pengguna, dan simpan email tersebut untuk berjaga-jaga jika pengguna menyelesaikan proses login dengan email pada perangkat yang sama.

    Swift

    Auth.auth().sendSignInLink(toEmail:email,
                               actionCodeSettings: actionCodeSettings) { error in
      // ...
        if let error = error {
          self.showMessagePrompt(error.localizedDescription)
          return
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        UserDefaults.standard.set(email, forKey: "Email")
        self.showMessagePrompt("Check your email for link")
        // ...
    }
    

    Objective-C

    [[FIRAuth auth] sendSignInLinkToEmail:email
                       actionCodeSettings:actionCodeSettings
                               completion:^(NSError *_Nullable error) {
      // ...
        if (error) {
          [self showMessagePrompt:error.localizedDescription];
           return;
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"];
        [self showMessagePrompt:@"Check your email for link"];
        // ...
    }];
    

Masalah keamanan

Guna mencegah link login digunakan untuk login sebagai pengguna yang tidak dimaksud atau pada perangkat yang tidak dimaksud, Firebase Auth mengharuskan pengguna untuk memasukkan alamat emailnya saat menyelesaikan proses login. Agar proses login berhasil, alamat email ini harus sama dengan alamat yang awalnya dikirimi link login.

Anda dapat menyederhanakan proses ini untuk pengguna yang membuka link login di perangkat yang sama dengan yang digunakan untuk meminta link. Cara menyederhanakannya, simpan alamat emailnya secara lokal saat Anda mengirimkan email login. Kemudian, gunakan alamat ini untuk menyelesaikan proses.

Setelah proses login selesai, semua mekanisme login yang sebelumnya tidak diverifikasi akan dihapus dari pengguna dan semua sesi yang ada menjadi tidak valid. Misalnya, jika seseorang sebelumnya membuat akun yang tidak diverifikasi dengan email dan sandi yang sama, maka sandi pengguna tersebut akan dihapus. Dengan begitu, peniru identitas yang mengklaim kepemilikan dan membuat akun yang tidak diverifikasi tersebut tidak akan dapat login lagi dengan akun yang sama.

Menyelesaikan proses login di aplikasi seluler iOS

Firebase Authentication menggunakan Firebase Dynamic Links untuk mengirim link email ke perangkat seluler. Untuk menyelesaikan proses login melalui aplikasi seluler, aplikasi harus dikonfigurasi untuk mendeteksi link aplikasi masuk, mengurai deep link yang mendasari, lalu menyelesaikan proses login.

Firebase Auth menggunakan Firebase Dynamic Links saat mengirimkan link yang dimaksudkan untuk dibuka di aplikasi seluler. Untuk menggunakan fitur ini, Dynamic Links perlu dikonfigurasi di Firebase Console.

  1. Mengaktifkan Firebase Dynamic Links:

    1. Di Firebase console, buka bagian Dynamic Links.
    2. Jika Anda belum menyetujui persyaratan Dynamic Links dan membuat domain Dynamic Links, lakukan sekarang.

      Jika Anda telah membuat domain Dynamic Links, catat domain tersebut. Domain Dynamic Links biasanya terlihat seperti contoh berikut:

      example.page.link

      Anda akan memerlukan nilai ini saat mengonfigurasi aplikasi iOS atau Android Anda untuk menghalangi link masuk.

  2. Mengonfigurasi aplikasi iOS:

    1. Jika Anda ingin menangani link ini dari aplikasi iOS yang dimiliki, Anda harus menentukan ID paket iOS di setelan project Firebase Console. Selain itu, ID App Store dan ID Apple Developer Team juga harus ditentukan.
    2. Anda juga harus mengonfigurasi domain pengendali tindakan email sebagai Domain Terkait pada kapabilitas aplikasi Anda. Secara default, pengendali tindakan email dihosting di domain seperti dalam contoh berikut:
      APP_ID.firebaseapp.com
    3. Jika ingin mendistribusikan aplikasi Anda ke iOS versi 8 atau yang lebih lama, Anda harus menetapkan ID paket iOS Anda sebagai skema kustom untuk URL masuk.
    4. Untuk mengetahui informasi selengkapnya, baca artikel Petunjuk Menerima Dynamic Links iOS.

Setelah Anda menerima link seperti yang dijelaskan di atas, pastikan link tersebut dimaksudkan untuk autentikasi link email dan selesaikan proses login.

Swift

if Auth.auth().isSignIn(withEmailLink: link) {
        Auth.auth().signIn(withEmail: email, link: self.link) { (user, error) in
          // ...
        }
}

Objective-C

if ([[FIRAuth auth] isSignInWithEmailLink:link]) {
    [[FIRAuth auth] signInWithEmail:email
                               link:link
                         completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      // ...
    }];
}

Untuk mempelajari cara menangani proses login dengan link email di aplikasi Android, baca Panduan Android.

Untuk mempelajari cara menangani proses login dengan link email di aplikasi web, baca Panduan Web.

Anda juga dapat menautkan metode autentikasi ini ke pengguna yang sudah ada. Misalnya, pengguna yang sebelumnya diautentikasi dengan penyedia lain, seperti nomor telepon, dapat menambahkan metode login ini ke akunnya yang sudah ada.

Perbedaannya terletak pada paruh kedua operasi:

Swift

  let credential = EmailAuthCredential.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.link(with: credential) { authData, error in
    if (error) {
      // And error occurred during linking.
      return
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthProvider credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      linkWithCredential:credential
              completion:^(FIRAuthDataResult *_Nullable result,
                           NSError *_Nullable error) {
    if (error) {
      // And error occurred during linking.
      return;
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }];

Metode ini juga dapat digunakan untuk mengautentikasi ulang pengguna link email sebelum menjalankan operasi yang sensitif.

Swift

  let credential = EmailAuthProvider.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in
    if (error) {
      // And error occurred during re-authentication.
      return
    }
    // The user was successfully re-authenticated.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthCredential credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      reauthenticateWithCredential:credential
                        completion:^(FIRAuthDataResult *_Nullable result,
                                     NSError *_Nullable error) {
    if (error) {
      // And error occurred during re-authentication
      return;
    }
    // The user was successfully re-authenticated.
  }];

Namun, karena proses ini dapat berakhir di perangkat berbeda yang dipakai pengguna awal tanpa login, proses ini mungkin tidak akan diselesaikan. Dalam hal ini, pesan error dapat ditampilkan kepada pengguna sehingga mereka harus membuka link di perangkat yang sama. Beberapa status dapat diteruskan di link untuk memberikan informasi tentang jenis operasi dan UID pengguna.

Jika Anda mendukung metode login dengan email berbasis sandi maupun link, gunakan fetchSignInMethodsForEmail untuk membedakan metode ini bagi pengguna melalui sandi/link. Cara ini berguna dalam proses ID-terlebih dahulu, yakni ketika pengguna diminta memasukkan emailnya terlebih dahulu, baru ditunjukkan metode login:

Swift

 // After asking the user for their email.
 Auth.auth().fetchSignInMethods(forEmail: email) { signInMethods, error in
   // This returns the same array as fetchProviders(forEmail:completion:) but for email
   // provider identified by 'password' string, signInMethods would contain 2
   // different strings:
   // 'emailLink' if the user previously signed in with an email/link
   // 'password' if the user has a password.
   // A user could have both.
   if (error) {
     // Handle error case.
   }
   if (!signInMethods.contains(EmailPasswordAuthSignInMethod)) {
     // User can sign in with email/password.
   }
   if (!signInMethods.contains(EmailLinkAuthSignInMethod)) {
     // User can sign in with email/link.
   }
 }

Objective-C

 // After asking the user for their email.
 [FIRAuth auth] fetchSignInMethodsForEmail:email
                                completion:^(NSArray *_Nullable signInMethods,
                                             NSError *_Nullable error) {
   // This returns the same array as fetchProvidersForEmail but for email
   // provider identified by 'password' string, signInMethods would contain 2
   // different strings:
   // 'emailLink' if the user previously signed in with an email/link
   // 'password' if the user has a password.
   // A user could have both.
   if (error) {
     // Handle error case.
   }
   if (![signInMethods containsObject:FIREmailPasswordAuthSignInMethod]) {
     // User can sign in with email/password.
   }
   if (![signInMethods containsObject:FIREmailLinkAuthSignInMethod]) {
     // User can sign in with email/link.
   }
 }];

Seperti yang dijelaskan di atas, email/sandi dan email/link dianggap sebagai FIREmailAuthProvider yang sama (PROVIDER_ID yang sama) dengan metode login yang berbeda.

Langkah berikutnya

Setelah pengguna login untuk pertama kalinya, akun pengguna baru akan dibuat dan ditautkan ke kredensial, yaitu nama pengguna dan sandi, nomor telepon, atau informasi penyedia autentikasi, yang digunakan pengguna tersebut untuk login. Akun baru ini disimpan sebagai bagian dari project Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam project, terlepas dari cara pengguna login.

  • Di dalam aplikasi, Anda bisa mendapatkan informasi profil dasar pengguna dari objek FIRUser. Baca bagian Mengelola Pengguna.

  • Di Aturan Keamanan Firebase Realtime Database dan Cloud Storage, Anda bisa mendapatkan ID pengguna unik yang login dari variabel auth, dan menggunakannya untuk mengontrol data yang dapat diakses oleh pengguna.

Anda dapat mengizinkan pengguna untuk login ke aplikasi menggunakan beberapa penyedia autentikasi dengan menautkan kredensial penyedia autentikasi ke akun pengguna yang ada.

Agar pengguna logout, panggil signOut::

Swift

    let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print ("Error signing out: %@", signOutError)
}  

Objective-C

    NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Anda juga dapat menambahkan kode penanganan error untuk berbagai error autentikasi. Baca bagian Menangani Error.