Memitigasi masalah login pengalihan rusak di browser yang memblokir akses penyimpanan pihak ketiga

Dokumen ini menjelaskan cara memitigasi masalah login pengalihan rusak di browser yang memblokir cookie pihak ketiga.

Ringkasan

Untuk memperlancar alur signInWithRedirect() bagi developer Firebase dan penggunanya, Firebase Authentication 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 solusi yang sangat jarang dipilih. Sebagai gantinya, Anda dapat menerapkan salah satu poin mitigasi berikut 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 aplikasi Anda dihosting dengan Firebase Hosting di domain kustom (ATAU web.app), gunakan Mitigasi #1.
  • Jika aplikasi Anda dihosting dengan layanan selain Firebase, gunakan Mitigasi #2, Mitigasi #3, Mitigasi #4, atau Mitigasi #5.

Mitigasi #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 mitigasi yang berbeda.)

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>"
    };
    
  2. 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.

Mitigasi #2: Beralih ke signInWithPopup()

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

Web version 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 version 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 poin mitigasi lainnya.

Mitigasi #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. Mitigasi ini dan yang berikutnya (untuk 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 bagian Mitigasi 1 untuk mengupdate redirect_uri yang diotorisasi dan authDomain Anda. Setelah Anda men-deploy ulang aplikasi, akses penyimpanan lintas-asal tidak akan tersedia lagi.

Mitigasi #4: Hosting sendiri kode helper login di domain Anda

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
    
  2. Hosting file di atas dalam domain aplikasi Anda. Pastikan server web Anda dapat merespons https://<app domain>/__/auth/<filename>.

    Berikut adalah contoh implementasi server yang mendownload dan menghosting file.

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

Mitigasi #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 version 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 version 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.