Safari 13+ iframe memblokir cookie CORS

9

Safari flat out tidak memungkinkan Anda mengatur cookie di iframe domain yang berbeda dari domain induk, header CORS di sisi server menjadi terkutuk.

Untuk memperjelas: pengguna ada di domainA.com. Iframe untuk domainB.com terbuka, dan upaya untuk mengotentikasi pengguna di domainB.com di dalam iframe. Set-Cookie header dikembalikan dari server di dalam domain iframe domainB.com, dengan semua header yang diperlukan, tetapi Safari tidak mengirimkannya kembali dalam panggilan berikutnya.

Pemecahan masalah lama adalah mengirimkan formulir dari iframe, dan mengatur cookie di respons. Saya kira mereka menyukai kenyataan bahwa pengguna mengklik sesuatu untuk mengirimkan formulir. Anda harus polling untuk cookie untuk melihat ketika respon kembali, karena pengiriman formulir tidak memiliki panggilan balik, dan dalam kasus cookie HttpOnly Anda tidak bisa, tapi hei, itu berhasil! Sampai tidak.

Kemudian, solusi yang lebih baru adalah mengarahkan pengguna ke domain iframe di jendela / tab baru, mengatur cookie acak di sana, dan sejak saat itu, subdomain itu "dipercaya" di dalam iframe. Sekali lagi, diperlukan klik untuk membuka jendela / tab baru, dan bahkan ada indikasi visual dari pembukaan tab baru. Banyak keamanan, standar seperti itu.

Dan sekarang, pada Safari 13 - Tidak ada lagi solusi. Tidak ada pengaturan cookie iframe yang lebih aman šŸ¤¬

Skema otentikasi lainnya tidak baik untuk kami (mis. Tajuk Auth-X). Kita perlu menggunakan cookie aman HttpOnly, karena kita tidak ingin token itu dengan cara apa pun diakses oleh sisi klien javascript.

Agar jelas, semuanya berfungsi dengan baik di browser lain.

Bugzilla WebKit yang relevan

Adakah yang punya saran?

Edit:

Terima kasih atas tautan @tomschmidt, sepertinya itu adalah arah yang benar. Saya mencoba menggunakan API Akses Penyimpanan Apple, tetapi sayangnya, meskipun saya memastikan untuk meminta akses sebelum menginisialisasi logika login saya dengan API:

requestStorageAccess = async() => {
    return new Promise(resolve => {
      //@ts-ignore
      document.requestStorageAccess().then(
        function () {
          console.log('Storage access was granted');
          resolve(true);
        },
        function () {
          console.log('Storage access was denied');
          resolve(false);
        }
      );    
    });
  }


const storageAccessGranted = await requestStorageAccess();
console.log(storageAccessGranted) // prints 'true'
await login();

Namun, cookie yang diterima pada respons / login API tidak dikirim dalam panggilan berikutnya ke API :(

Tom Teman
sumber
Pastikan ini hanya dipicu pada interaksi eksplisit dengan iframe, seperti onclick.
tomschmidt
1
Ya, itulah yang saya lakukan. Lihatlah masalah webkit bugzilla yang saya tautkan, saya kira ini adalah bug aktual pada akhir Safari: /
Tom Teman
Masalahnya bukan bahwa cookie tidak terkirim. Jika Anda meminta akses penyimpanan, cookie yang ada dikirim ke server. Masalahnya adalah semua cookie baru tidak disimpan sama sekali, sehingga cookie itu tidak ada di sana untuk dikirim.
Matt Cosentino
@MattCosentino ya, itulah yang saya maksud - "cookie yang diterima pada respons / login API" adalah cookie baru yang dikirim kembali dalam respons tajuk Set-Cookie ke domain iframe, tetapi panggilan berikutnya dari domain iframe tidak termasuk yang cookie dalam permintaan. Jadi ya, lebih tepat untuk mengatakan bahwa akar masalahnya adalah tidak ada cookie baru yang disimpan di browser dalam skenario ini.
Tom Teman

Jawaban:

1

Saya pikir saya mungkin telah menemukan solusinya: API Akses Penyimpanan Apple: https://webkit.org/blog/8124/introducing-storage-access-api/

tomschmidt
sumber
Hei, terima kasih untuk idenya, tapi aku khawatir itu tidak berhasil (lihat jawaban saya edit)
Tom Teman
1
Saya juga mengalami masalah yang sama dengan safari 13. Ada solusi?
Niroshana
0

Jadi, solusinya masih agak berfungsi, selama jendela baru menyimpan cookie yang ingin Anda simpan. Iframe masih tidak dapat menyimpan cookie itu sendiri. Dalam kasus saya, yang saya butuhkan adalah cookie id sesi. Jadi, saya membuka jendela sembulan kecil ketika pengguna memberikan akses penyimpanan. Ia mendapat dan menyimpan cookie id sesi, menutup, dan memuat ulang iframe. Iframe kemudian memiliki akses ke cookie id sesi dan mengirimkannya dalam permintaan berikutnya. Saya pikir ini hanya sementara, sepertinya mereka akan menghapus akses penyimpanan dari jendela sembulan di masa depan. Mungkin mereka akan memperbaiki iframe yang tidak dapat menyimpan cookie saat itu.

Matt Cosentino
sumber
Matt, saya telah menggunakan solusi serupa dengan pop up, yang berfungsi pada desktop Safari 13.1, tetapi pengujian pada iPad Safari 13.4 tidak berfungsi. Apakah Anda bisa membuatnya berfungsi di iPad? Thnx
teamdane