Praktik terbaik untuk menggunakan signInWithRedirect di browser yang memblokir akses penyimpanan pihak ketiga

Dokumen ini menjelaskan praktik terbaik untuk menggunakan login pengalihan di browser yang memblokir cookie pihak ketiga. Anda harus mengikuti salah satu opsi yang tercantum di sini agar signInWithRedirect() dapat berfungsi sebagaimana mestinya di lingkungan produksi, di semua browser.

Ringkasan

Agar alur signInWithRedirect() lancar bagi Anda dan pengguna, Firebase Authentication JavaScript SDK menggunakan iframe lintas-asal yang terhubung ke domain Firebase Hosting aplikasi Anda. Namun, mekanisme ini tidak efektif untuk browser yang memblokir akses penyimpanan pihak ketiga.

Meminta pengguna untuk menonaktifkan fitur partisi penyimpanan di browser merupakan opsi yang sangat jarang dilakukan. Sebagai gantinya, sebaiknya terapkan salah satu opsi penyiapan berikut ini ke aplikasi, tergantung pada detail kasus penggunaan Anda.

  • Jika aplikasi Anda dihosting dengan Firebase Hosting di subdomain firebaseapp.com, Anda tidak akan terpengaruh oleh masalah ini dan tidak perlu melakukan tindakan apa pun.
  • Jika Anda menghosting aplikasi dengan Firebase Hosting di domain kustom atau subdomain web.app, gunakan Opsi 1.
  • Jika aplikasi Anda dihosting dengan layanan selain Firebase, gunakan Opsi 2, Opsi 3, Opsi 4, atau Opsi 5.

Opsi 1: Perbarui konfigurasi Firebase untuk menggunakan domain kustom Anda sebagai authDomain

Jika aplikasi Anda dihosting dengan Firebase Hosting menggunakan domain kustom, Anda dapat mengonfigurasi Firebase SDK untuk menggunakan domain kustom sebagai authDomain. Hal ini untuk memastikan bahwa aplikasi Anda dan iframe auth menggunakan domain yang sama, sehingga masalah login dapat dicegah. (Jika tidak menggunakan Firebase Hosting, Anda harus menggunakan opsi yang berbeda.). Pastikan Anda telah menyiapkan domain kustom di project yang sama dengan yang digunakan untuk autentikasi.

Untuk memperbarui konfigurasi Firebase agar domain kustom digunakan sebagai domain auth, lakukan langkah berikut:

  1. Konfigurasikan Firebase JS SDK untuk menggunakan domain kustom Anda sebagai authDomain:

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
  1. Tambahkan authDomain baru ke daftar URI pengalihan yang telah diotorisasi penyedia Oauth. Cara melakukannya akan bergantung pada penyedia, tetapi secara umum Anda dapat mengikuti bagian "Sebelum memulai" di penyedia mana pun untuk melihat petunjuk yang tepat (misalnya, penyedia Facebook). Tampilan URI yang diperbarui untuk diotorisasi mirip dengan https://<the-domain-that-serves-your-app>/__/auth/handler — unsur /__/auth/handler di akhir bersifat penting.

    Demikian pula, jika Anda menggunakan penyedia SAML, tambahkan authDomain baru ke URL SAML Assertion Consumer Service (ACS).

  2. Pastikan continue_uri Anda ada dalam daftar domain yang diizinkan.

  3. Deploy ulang dengan Firebase Hosting jika diperlukan untuk mengambil file konfigurasi Firebase terbaru yang dihosting di /__/firebase/init.json.

Opsi 2: Beralih ke signInWithPopup()

Gunakan signInWithPopup(), bukan signInWithRedirect(). Kode aplikasi Anda lainnya tetap sama, tetapi objek UserCredential diambil secara berbeda.

Web versi 9

  // Before
  // ==============
  signInWithRedirect(auth, new GoogleAuthProvider());
  // After the page redirects back
  const userCred = await getRedirectResult(auth);

  // After
  // ==============
  const userCred = await signInWithPopup(auth, new GoogleAuthProvider());

Web versi 8

  // Before
  // ==============
  firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
  // After the page redirects back
  var userCred = await firebase.auth().getRedirectResult();

  // After
  // ==============
  var userCred = await firebase.auth().signInWithPopup(
      new firebase.auth.GoogleAuthProvider());
```

Login dengan jendela pop-up tidak selalu ideal bagi pengguna. Jendela pop-up terkadang diblokir oleh perangkat atau platform, dan alurnya kurang lancar bagi pengguna perangkat seluler. Jika penggunaan pop-up menimbulkan masalah bagi aplikasi, Anda harus mengikuti salah satu opsi lainnya.

Opsi 3: Proses permintaan proxy auth ke firebaseapp.com

Alur signInWithRedirect dimulai dengan melakukan pengalihan dari domain aplikasi Anda ke domain yang ditentukan dalam parameter authDomain di konfigurasi Firebase (".firebaseapp.com" secara default). authDomain menghosting kode helper login yang melakukan pengalihan ke Penyedia Identitas, yang jika berhasil, akan mengalihkan kembali ke domain aplikasi.

Saat alur autentikasi kembali ke domain aplikasi Anda, penyimpanan browser domain helper login akan diakses. Opsi ini dan yang berikutnya (menghosting sendiri kode) akan menghilangkan akses penyimpanan lintas-asal sehingga tidak diblokir oleh browser.

  1. Siapkan reverse proxy di server aplikasi Anda agar permintaan GET/POST ke https://<app domain>/__/auth/ diteruskan ke https://<project>.firebaseapp.com/__/auth/. Pastikan bahwa penerusan ini bersifat transparan untuk browser; ini tidak dapat dilakukan melalui Pengalihan 302.

    Jika Anda menggunakan nginx untuk menyalurkan domain kustom, konfigurasi reverse-proxy akan terlihat seperti ini:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. Ikuti langkah-langkah di Opsi 1 untuk mengupdate redirect_uri yang diotorisasi, URL ACS, dan authDomain. Setelah Anda men-deploy ulang aplikasi, akses penyimpanan lintas-asal tidak akan tersedia lagi.

Opsi 4: Hosting sendiri kode helper login di domain Anda

Cara lain untuk menghilangkan akses penyimpanan lintas-asal adalah menghosting sendiri kode helper login dengan Firebase. Namun, pendekatan ini tidak efektif untuk login dengan Apple atau SAML. Gunakan opsi ini hanya jika penyiapan reverse-proxy di opsi 3 tidak memungkinkan.

Hosting kode helper memiliki langkah-langkah berikut:

  1. Download file yang akan dihosting dari lokasi <project>.firebaseapp.com dengan menjalankan perintah berikut:

    mkdir signin_helpers/ && cd signin_helpers
    wget https://<project>.firebaseapp.com/__/auth/handler
    wget https://<project>.firebaseapp.com/__/auth/handler.js
    wget https://<project>.firebaseapp.com/__/auth/experiments.js
    wget https://<project>.firebaseapp.com/__/auth/iframe
    wget https://<project>.firebaseapp.com/__/auth/iframe.js
    wget https://<project>.firebaseapp.com/__/firebase/init.json
    
  2. Hosting file di atas dalam domain aplikasi Anda. Pastikan server web Anda dapat merespons https://<app domain>/__/auth/<filename> dan https://<app domain>/__/firebase/init.json.

    Berikut adalah contoh implementasi server yang mendownload dan menghosting file. Sebaiknya download dan sinkronkan file secara berkala untuk memastikan perbaikan bug dan fitur terbaru diterapkan.

  3. Ikuti langkah-langkah di Opsi 1 untuk mengupdate redirect_uri yang diotorisasi dan authDomain Anda. Setelah Anda men-deploy ulang aplikasi, akses penyimpanan lintas-asal tidak akan tersedia lagi.

Opsi 5: Tangani login penyedia secara independen

Firebase Authentication SDK menyediakan signInWithPopup() dan signInWithRedirect() sebagai metode yang mudah untuk menggabungkan logika yang rumit sehingga tidak perlu melibatkan SDK lain. Anda dapat menghindari penggunaan salah satu metode tersebut sepenuhnya dengan login ke penyedia Anda secara independen, lalu menggunakan signInWithCredential() untuk menukar kredensial penyedia dengan kredensial Firebase Authentication. Misalnya, Anda dapat menggunakan Google Sign In SDK, kode contoh untuk mendapatkan kredensial Akun Google, lalu membuat instance kredensial Google yang baru, dengan menjalankan kode berikut:

Web versi 9

  // `googleUser` from the onsuccess Google Sign In callback.
  //  googUser = gapi.auth2.getAuthInstance().currentUser.get();
  const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
  const result = await signInWithCredential(auth, credential);

Web versi 8

  // `googleUser` from the onsuccess Google Sign In callback.
  const credential = firebase.auth.GoogleAuthProvider.credential(
      googleUser.getAuthResponse().id_token);
  const result = await firebase.auth().signInWithCredential(credential);

Setelah Anda memanggil signInWithCredential(), fungsi aplikasi Anda lainnya akan berfungsi sama seperti sebelumnya.

Petunjuk untuk mendapatkan kredensial Apple bisa diakses di sini.