Bagaimana cara menangani beberapa cookie dengan nama yang sama?

92

Misalnya, saya memiliki aplikasi yang mengirimkan header HTTP berikut untuk disetel ke cookie bernama "a":

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1

Jika saya mengakses /exampledi server, kedua jalur tersebut valid, jadi saya memiliki dua cookie bernama "a"! Karena browser tidak mengirimkan informasi jalur apa pun, kedua cookie tidak dapat dibedakan.

Cookie: a=2; a=1

Bagaimana seharusnya kasus ini ditangani? Pilih yang pertama? Buat daftar dengan semua nilai cookie? Atau haruskah kasus seperti itu dianggap sebagai kesalahan pengembang?

deamon
sumber
Saya akan melakukan yang terbaik (baca: semua yang saya bisa) untuk menghindari nama cookie duplikat. Kebanyakan orang tidak pernah mengalami masalah ini - untuk alasan yang bagus.
Situs web hanya dapat membaca cookie-nya sendiri. Itu tidak dapat membaca cookie dari situs web / domain lain. Keamanan ini dijamin oleh browser. Ini mungkin tip untuk pemula absolut (saya bingung)
Arun

Jawaban:

38

Dari artikel ini di SitePoint :

Jika beberapa cookie dengan nama yang sama cocok dengan URI permintaan yang diberikan, salah satunya akan dipilih oleh browser.

Semakin spesifik jalurnya, semakin tinggi prioritasnya. Namun prioritas berdasarkan atribut lain, termasuk domain, tidak ditentukan, dan mungkin berbeda di antara browser. Ini berarti bahwa jika Anda telah menyetel cookie dengan nama yang sama terhadap ".example.org" dan "www.example.org", Anda tidak dapat memastikan cookie mana yang akan dikirim kembali.

Sunting: informasi dari 2010 ini tampaknya sudah ketinggalan zaman, tampaknya browser sekarang dapat mengirim beberapa cookie sebagai imbalan, lihat jawaban oleh @Nate di bawah untuk detailnya

Jan M
sumber
9
Jadi bagaimana cara menghapus beberapa cookie yang identik? Saya telah memaluinya selama dua hari sekarang dan cookie duplikat tampaknya tidak bisa dihancurkan.
Bob Jones
13
@Brant Artikel itu mungkin sedikit salah - Saya baru saja melihat Chrome mengirim kembali dua cookie dengan nama yang sama (tetapi jalur berbeda), jadi "yang satu dipilih oleh browser" belum tentu benar. Cookie jalur terdalam dikirim lebih dulu, BTW, yang tampaknya masuk akal. Dan cookie lain juga dibuat di antaranya.
Jonas N
3
Firefox (15) juga mengirimkan dua cookie dengan nama yang sama! jika ditemukan dengan dua cookie dengan untuk domain .a.comdan hosta.com
Taha Jahangir
Memang informasi ini salah. Jawaban @ Nate harus saya tandai sebagai benar.
Dan Milon
5
404: Jawaban @ Nate yang terkenal tidak ditemukan.
d.popov
90

Jawaban yang mengacu pada artikel di SitePoint tidak sepenuhnya lengkap. Silakan lihat RFC 6265 (agar adil, RFC ini dirilis pada tahun 2011 setelah pertanyaan ini diposting, yang menggantikan RFC 2965 sebelumnya dari tahun 2000 dan RFC 2109 dari tahun 1997).

Bagian 5.4 , sub-bagian 2 mengatakan ini:

Agen pengguna HARUS mengurutkan daftar cookie dalam urutan berikut:

  • Cookie dengan jalur yang lebih panjang dicantumkan sebelum cookie dengan jalur yang lebih pendek.

CATATAN: Tidak semua agen pengguna mengurutkan daftar cookie dalam urutan ini, tetapi urutan ini mencerminkan praktik umum saat dokumen ini ditulis, dan, secara historis, ada server yang (secara keliru) bergantung pada pesanan ini.

Ada juga permata kecil ini di bagian 4.2.2 :

... server TIDAK HARUS bergantung pada urutan serialisasi. Khususnya, jika header Cookie berisi dua cookie dengan nama yang sama (misalnya, yang disetel dengan atribut Path atau Domain yang berbeda), server TIDAK HARUS bergantung pada urutan cookie ini muncul di header.

Dalam contoh permintaan kuki ( Cookie: a = 2; a = 1 ) perhatikan bahwa kuki yang disetel dengan jalur / contoh ( a = 2 ) memiliki jalur yang lebih panjang daripada yang memiliki jalur / ( a = 1 ) dan begitu juga dikirim kembali kepada Anda di baris pertama, yang sesuai dengan rekomendasi spesifikasi. Dengan demikian Anda kurang lebih benar dalam asumsi Anda bahwa Anda dapat memilih nilai pertama.

Sayangnya bahasa yang digunakan di RFC sangat spesifik - penggunaan kata-kata HARUS dan TIDAK HARUS menimbulkan ambiguitas di RFC. Ini menunjukkan konvensi yang harus diikuti, tetapi tidak diperlukan untuk menjadi konforman dengan spesifikasi. Meskipun saya memahami RFC dengan cukup baik, saya belum melakukan penelitian untuk melihat apa yang dilakukan klien dunia nyata; ada kemungkinan satu atau lebih browser atau perangkat lunak lain yang bertindak sebagai klien HTTP mungkin tidak mengirim cookie jalur terpanjang (mis.: / example ) terlebih dahulu di header Cookie:.

Jika Anda berada dalam posisi untuk mengontrol nilai cookie dan Anda ingin membuat solusi Anda sangat mudah, Anda sebaiknya:

  1. menggunakan nama cookie yang berbeda untuk diganti di jalur tertentu, seperti:

    • Set-cookie: a-global = 1; Path = /; Version = 1
    • Set-cookie: a-example = 2; Path = / example; Versi = 1
  2. menyimpan jalur yang Anda butuhkan dalam nilai cookie itu sendiri:

    • Set-cookie: a = 1 & path = /; Path = /; Version = 1
    • Set-cookie: a = 2 & path = / example; Path = / example; Versi = 1

Kedua solusi ini memerlukan logika tambahan di server untuk memilih nilai cookie yang diinginkan, dengan membandingkan URL yang diminta dengan daftar cookie yang tersedia. Tidak terlalu cantik. Sayangnya RFC tidak memiliki pandangan jauh ke depan untuk mensyaratkan jalur yang lebih panjang sepenuhnya menimpa cookie dengan jalur yang lebih pendek (misalnya: dalam contoh Anda, Anda akan menerima Cookie: a = 2 saja ).

Simpanse yang suka berperang
sumber
2
Terima kasih telah menggali ini dari RFC sialan ini! // mengapa repot-repot membacanya jika tidak ada yang mengikuti rekomendasi ini? ..
Rast
3
Sepertinya Wildfly 8.0 memperhatikan urutan cookie dan menggunakan yang pertama. Ini memungkinkan kami menjalankan aplikasi lain dalam konteks 'bersarang'. Namun, itu akan gagal jika beberapa browser tidak mengikuti rekomendasi RFC. Cara yang benar untuk melakukan ini dengan menyetel nama yang berbeda dari cookie sesi, seperti JSESSIONID2.
honzajde
2
Saya menguji browser utama setelah membaca jawaban Anda: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 Dan mereka semua tampaknya menanganinya dengan benar bahwa Cookie dengan jalur yang lebih panjang berada sebelum cookie dengan jalur yang lebih pendek. Dan di PHP (diuji pada versi 7) hanya membaca cookie pertama yang disetel ke variabel $ _COOKIE.
Alexander Schranz
1
Apakah path=/;Path=/spesifikasi sesuai dengan FRC-6265? Saya tidak menemukan penyebutan tersebut. Tomcat mengancam ";" di jalur sebagai simbol yang salah
Hubbitus
1
@Hubbitus Perhatikan, biar a=2&path=/example;Path=/exampletidak ada yang ;jalan.
Franklin Yu
2

Tidak ada yang salah dengan memiliki beberapa nilai untuk nama yang sama ... jika Anda menginginkannya. Anda bahkan mungkin menyematkan konteks tambahan dalam nilai.

Jika tidak, maka tentu saja nama yang berbeda adalah solusi jika Anda menginginkan kedua konteks tersebut.

Alternatifnya adalah mengirim nama cookie yang sama dengan jalur (dan domain) yang sama bahkan dari jalur yang lebih spesifik. Instruksi cookie yang ditetapkan tersebut akan menimpa nilai cookie itu.

Sekarang setelah Anda mengetahui bagian terpenting (cara kerjanya), dan Anda dapat mencapai apa yang Anda butuhkan dengan beberapa cara berbeda, jawaban saya untuk pertanyaan Anda adalah: ini adalah masalah pengembang.

Gerard ONeill
sumber
0

Saya pasti mengetahui aplikasi yang melakukan ini secara ekstensif menggunakan beberapa id sesi - dan tampaknya bekerja secara konsisten. Namun saya tidak tahu - dan tidak berniat untuk mencari tahu - apakah mereka melakukannya karena browser mengembalikan cookie dalam urutan yang konsisten tergantung pada kapan mereka disetel / jalur mana mereka ditetapkan atau apakah aplikasi mencoba mencocokkan masing-masing satu ke sesi yang ada.

Saya sangat menyarankan agar praktik ini dihindari.

Namun jika Anda benar-benar ingin tahu bagaimana browser (dan aplikasi) menangani skenario ini, mengapa tidak membangun rig pengujian dan mencobanya.

symcbean
sumber
2
Server tidak memiliki kendali atas apa yang dikirimkan kepadanya oleh browser. Itu masih perlu ditangani.
Martin OConnor
0

Jika Anda menggunakan kerangka kerja Java / Scala, Mainkan: hati-hati! Jika permintaan berisi beberapa cookie dengan nama yang sama, Play hanya akan menampilkan 1 cookie di kode Anda.

Erik van Oosten
sumber
-2

Jika Anda perlu membedakannya, Anda harus memberi nilai kunci yang berbeda.

Yogurt
sumber