Cookie di localhost dengan domain eksplisit

191

Saya harus kehilangan beberapa hal mendasar tentang cookie. Di localhost, ketika saya menetapkan cookie di sisi server dan menentukan domain secara eksplisit sebagai localhost (atau .localhost). cookie sepertinya tidak diterima oleh beberapa browser.

Firefox 3.5: Saya memeriksa permintaan HTTP di Firebug. Apa yang saya lihat adalah:

Set-Cookie:
    name=value;
    domain=localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

atau (ketika saya mengatur domain ke .localhost):

Set-Cookie:
    name=value;
    domain=.localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

Dalam kedua kasus, cookie tidak disimpan.

IE8: Saya tidak menggunakan alat tambahan, tetapi cookie sepertinya tidak disimpan juga, karena tidak dikirim kembali dalam permintaan berikutnya.

Opera 9.64: Baik localhost dan .localhost berfungsi , tetapi ketika saya memeriksa daftar cookie di Preferensi, domain diatur ke localhost.local meskipun terdaftar di bawah localhost (dalam pengelompokan daftar).

Safari 4: Baik localhost dan .localhost berfungsi , tetapi mereka selalu terdaftar sebagai .localhost di Preferensi. Di sisi lain, cookie tanpa domain eksplisit, itu ditampilkan sebagai hanya localhost (tanpa titik).

Apa masalah dengan localhost? Karena sejumlah inkonsistensi, harus ada beberapa aturan khusus yang melibatkan localhost. Juga, tidak sepenuhnya jelas bagi saya mengapa domain harus diawali dengan titik? RFC 2109 secara eksplisit menyatakan bahwa:

Nilai untuk atribut Domain tidak mengandung titik yang disematkan atau tidak dimulai dengan titik.

Mengapa? Dokumen tersebut menunjukkan bahwa ia harus melakukan sesuatu dengan keamanan. Saya harus mengakui bahwa saya belum membaca keseluruhan spesifikasi (mungkin melakukannya nanti), tetapi kedengarannya agak aneh. Berdasarkan ini, pengaturan cookie di localhost tidak mungkin.

Jan Zich
sumber
14
Utas berusia 6 tahun dan ini masih menjadi masalah. Saya menggunakan Chrome v40. Lihat di sini .
Gaui
5
Chrome 43 ... masih bug.
Evan Carroll
4
Chrome 54 di sini, TIDAK diselesaikan
Vahid Amiri
6
Chrome 73 .. masih menghadapi masalah yang sama. :(
Code_Crash
2
Adakah yang bisa menyelesaikan ini? Masih menghadapi masalah yang sama .. lihat jawaban SO ini
Bonjour123

Jawaban:

236

Secara desain, nama domain harus memiliki setidaknya dua titik; jika tidak, browser akan menganggapnya tidak valid. (Lihat referensi di http://curl.haxx.se/rfc/cookie_spec.html )

Saat bekerja localhost, domain cookie harus dihilangkan seluruhnya. Mengaturnya ke ""atau NULLatau FALSEbukannya "localhost"tidak cukup.

Untuk PHP, lihat komentar di http://php.net/manual/en/function.setcookie.php#73107 .

Jika bekerja dengan Java Servlet API, jangan panggil cookie.setDomain("...")metode ini sama sekali.

Ralph Buchfelder
sumber
93
Tidak yakin mengapa semua orang memberi ini +1, saya mengatur domain kuki menjadi string nol atau salah atau kosong dan masih tidak menyimpan jika di localhost.
Justin
5
Saya tidak melihat di mana pun di RFC6265 tentang dua titik di domain: tools.ietf.org/html/rfc6265#section-5.2.3 .Net mengatakan atur ke ".local" untuk semua host di domain lokal Anda. Yang tampaknya konsisten dengan Opera / Safari msdn.microsoft.com/en-us/library/ckch3yd2.aspx
MandoMando
9
@Justin: Hm, Anda mungkin perlu menghilangkan Domain=parameter saat mengatur cookie. Jika Anda hanya mengatur domain ke nol atau kosong, mungkin kerangka kerja Anda akan mengirim Domain=parameter dengan nilai itu, alih-alih menghilangkannya? Periksa dengan misalnya Firebug.
sleske
2
@Ralph, satu juta terima kasih, benda ini membuatku gila selama beberapa jam. Mudah-mudahan mengatur Domain ke null (Saya berada di tumpukan .Net server) berfungsi seperti pesona.
Xose Lluis
4
Kata ini agak buruk. "Mengeset ke null atau false atau string kosong" harus membaca "Sama sekali tidak mengatur bagian 'domain' dari cookie." Misalnya, menggunakan tes sederhana untuk sepenuhnya meninggalkan bagian domain dari karya cookie untuk localhost:((domain && domain !== "localhost") ? ";domain="+domain : "")
L0j1k
34

Saya secara luas setuju dengan @Ralph Buchfelder, tetapi inilah beberapa amplifikasi dari ini, dengan bereksperimen ketika mencoba mereplikasi sistem dengan beberapa subdomain (seperti example.com, fr.example.com, de.example.com) pada mesin lokal saya ( OS X / Apache / Chrome | Firefox).

Saya telah mengedit / etc / hosts untuk menunjukkan beberapa subdomain imajiner di 127.0.0.1:

127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com

Jika saya bekerja di fr.localexample.com dan saya mengabaikan parameter domain, cookie disimpan dengan benar untuk fr.localexample.com, tetapi tidak terlihat di subdomain lainnya.

Jika saya menggunakan domain dari ".localexample.com", cookie disimpan dengan benar untuk fr.localexample.com, dan adalah terlihat di subdomain lainnya.

Jika saya menggunakan domain "localexample.com", atau ketika saya mencoba domain hanya "localexample" atau "localhost", cookie itu tidak disimpan.

Jika saya menggunakan domain "fr.localexample.com" atau ".fr.localexample.com", cookie disimpan dengan benar untuk fr.localexample.com dan (benar) tidak terlihat di subdomain lain.

Jadi persyaratan bahwa Anda memerlukan setidaknya dua titik di domain tampaknya benar, meskipun saya tidak dapat melihat mengapa itu seharusnya.

Jika ada yang ingin mencoba ini, berikut ini beberapa kode yang berguna:

<html>
<head>
<title>
Testing cookies
</title>
</head>
<body>
<?php
header('HTTP/1.0 200');
$domain = 'fr.localexample.com';    // Change this to the domain you want to test.
if (!empty($_GET['v'])) {
    $val = $_GET['v'];
    print "Setting cookie to $val<br/>";
    setcookie("mycookie", $val, time() + 48 * 3600, '/', $domain);
}
print "<pre>";
print "Cookie:<br/>";
var_dump($_COOKIE);
print "Server:<br/>";
var_dump($_SERVER);
print "</pre>";
?>
</body>
</html>
xgretsch
sumber
30

localhost: Anda dapat menggunakan: domain: ".app.localhost"dan itu akan berhasil. The 'domain' parameter kebutuhan 1 atau lebih titik dalam nama domain untuk pengaturan cookies. Maka Anda dapat memiliki sesi bekerja di subdomain localhost seperti: api.app.localhost:3000.

AmpT
sumber
1
Juga diuji dan bekerja pada server node.js, menggunakan Express 3.x, inexpress.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
AmpT
3
INI harus dipilih sebagai jawaban jika Anda menggunakan domain lokal! Menempatkan titik sebelum subdomain memperbaiki masalah saya.
Foxhoundn
1
Jadi, dari mana .app.datangnya pertandaan ini ? Apakah itu bagian dari beberapa SPEC? Dan apakah itu berlaku untuk semua domain yang tidak sesuai (yang tanpa dua titik)? Juga, apakah ini akan berfungsi dengan browser lama? : ^)
user2173353
Oh ... Saya mengerti sekarang ... Ini hanya tipuan untuk mengelabui browser. BAIK.
user2173353
14

Ketika cookie diatur dengan domain eksplisit 'localhost' sebagai berikut ...

Set-Cookie: name = value; domain = localhost ; kedaluwarsa = Kamis, 16-Jul-2009 21:25:05 GMT; path = /

... maka browser mengabaikannya karena tidak menyertakan setidaknya dua periode dan bukan salah satu dari tujuh domain tingkat atas yang ditangani secara khusus .

... domain harus memiliki setidaknya dua (2) atau tiga (3) periode di dalamnya untuk mencegah domain dari bentuk: ".com", ".edu", dan "va.us". Setiap domain yang gagal dalam salah satu dari tujuh domain tingkat atas khusus yang tercantum di bawah ini hanya memerlukan dua periode. Domain lainnya membutuhkan setidaknya tiga. Tujuh domain tingkat atas khusus adalah: "COM", "EDU", "NET", "ORG", "GOV", "MIL", dan "INT".

Perhatikan bahwa jumlah periode di atas mungkin mengasumsikan bahwa periode terkemuka diperlukan. Namun periode ini diabaikan di peramban modern dan mungkin seharusnya dibaca ...

setidaknya satu (1) atau dua (2) periode

Perhatikan bahwa nilai default untuk atribut domain adalah nama host dari server yang menghasilkan respons cookie .

Jadi solusi untuk cookie yang tidak disetel untuk localhost adalah tidak menentukan atribut domain dan membiarkan browser menggunakan nilai default - ini tampaknya tidak memiliki kendala yang sama dengan nilai eksplisit dalam atribut domain.

Scott Munro
sumber
Saya tidak melakukan DV, tetapi saya menduga alasan yang dilakukan orang lain adalah karena jawaban Anda tidak terlalu menambah nilai. Persyaratan dua periode dan membiarkan atribut domain kosong keduanya telah dibahas dalam jawaban lain. Juga, hal-hal yang Anda tambahkan tentang domain tingkat atas tampaknya tidak benar. Dalam pengalaman saya itu bukan keharusan.
TTT
@TTT Tidak yakin jika Anda mendapat sedikit jawaban saya di mana saya mengatakan bahwa itu harus setidaknya 1 atau dua periode tergantung pada TLD karena periode terkemuka diabaikan? Jadi saya memberikan beberapa latar belakang tentang masalah ini dan menambahkan poin yang menurut saya tidak dibahas di tempat lain - aturannya berbeda untuk domain eksplisit dan yang default browser-nya. Sepertinya itu menambah nilai bagi saya.
Scott Munro
1
Meninggalkan domain nol (tidak menyetelnya sama sekali) TIDAK menyebabkan Chrome menyimpan cookie untuk hosting lokal. Itu masih mengabaikannya. Perhatikan bahwa ini hanya berlaku untuk cookie "permanen" (cookie yang menetapkan tanggal kedaluwarsa), karena cookie tersebut akan bergantung pada cookie "sesi" untuk localhost (cookie yang tidak menetapkan tanggal kedaluwarsa).
Triynko
3

Hasil yang saya peroleh bervariasi berdasarkan browser.

Chrome- 127.0.0.1 berfungsi tetapi localhost .localhost dan "" tidak. Firefox- .localhost berfungsi tetapi localhost, 127.0.0.1, dan "" tidak.

Belum diuji di Opera, IE, atau Safari


sumber
3
Baru saja mengujinya dengan Chrome V.22.0.1229.94 m: Mengatur cookie untuk localhost tanpa memberikan Domain=parameter berfungsi. Domain=juga berfungsi, tetapi Domain=localhosttidak.
sleske
3

Menghabiskan banyak waktu untuk memecahkan masalah ini sendiri.

Menggunakan PHP, dan Tidak ada di halaman ini yang berfungsi untuk saya. Saya akhirnya menyadari dalam kode saya bahwa parameter 'aman' ke PHP session_set_cookie_params () selalu disetel ke TRUE.

Karena saya tidak mengunjungi localhost dengan https browser saya tidak akan pernah menerima cookie. Jadi, saya memodifikasi bagian dari kode saya untuk secara kondisional menetapkan parameter 'aman' berdasarkan $ _SERVER ['HTTP_HOST'] menjadi 'localhost' atau tidak. Bekerja dengan baik sekarang.

Saya harap ini membantu seseorang.

James Jacobson
sumber
2

Jika Anda mengatur cookie dari domain lain (yaitu Anda mengatur cookie dengan membuat permintaan asal silang XHR), maka Anda perlu memastikan bahwa Anda menetapkan withCredentialsatribut ke true pada XMLHttpRequest yang Anda gunakan untuk mengambil cookie seperti yang dijelaskan di sini

Aidan Ewen
sumber
ya bahkan dengan itu. Itu masih tidak berfungsi dengan permintaan lintas-domain. Browser - Safari, IE 11
Rohit Kumar
2

Anda dapat menggunakan localhost.orgatau lebih tepatnya .localhost.orgitu akan selalu diselesaikan127.0.0.1

qoomon
sumber
1

Saya lebih beruntung menguji secara lokal menggunakan 127.0.0.1 sebagai domain. Saya tidak yakin mengapa, tetapi saya memiliki hasil yang beragam dengan localhost dan .localhost, dll.

toby
sumber
1

Tidak satu pun dari perbaikan yang disarankan bekerja untuk saya - mengaturnya ke nol, salah, menambahkan dua titik, dll - tidak berfungsi.

Pada akhirnya, saya baru saja menghapus domain dari cookie jika itu adalah localhost dan sekarang berfungsi untuk saya di Chrome 38 .

Kode sebelumnya (tidak berfungsi):

document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';

Kode baru (sekarang berfungsi):

 if(document.domain === 'localhost') {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';path=/;' ;
    } else {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
    }
DJ_Polly
sumber
1

Saya memiliki masalah yang sama dan saya memperbaikinya dengan meletakkan 2 titik di nama cookie itu sendiri tanpa menentukan domain apa pun.

set-cookie: name.s1.s2=value; path=/; expires=Sun, 12 Aug 2018 14:28:43 GMT; HttpOnly
Eric B.
sumber
1

Tampaknya ada masalah saat Anda menggunakan https://<local-domain>lalu http://<local-domain>. Situs http://tidak mengirim cookie dengan permintaan setelah https://situs menetapkannya. Paksa memuat ulang dan menghapus cache tidak membantu. Hanya pembersihan manual cookie yang berfungsi. Juga, jika saya menghapusnya di https://halaman, maka http://halaman mulai bekerja lagi.

Tampaknya terkait dengan "Cookie aman yang ketat". Penjelasan yang bagus di sini . Itu dirilis di Chrome 58 pada 2017-04-19.

Sepertinya Chrome memang merekam cookie aman dan cookie tidak aman karena akan menampilkan cookie yang benar tergantung pada protokol halaman saat mengklik ikon bilah alamat.

Tetapi Developer tools > Application > Cookiestidak akan menampilkan cookie tidak aman ketika ada cookie aman dengan nama yang sama untuk domain yang sama, juga tidak akan mengirim cookie tidak aman dengan permintaan apa pun. Ini sepertinya bug Chrome, atau jika perilaku ini diharapkan, harus ada beberapa cara untuk melihat cookie aman saat dihttp halaman dan indikasi bahwa tersebut sedang ditimpa.

Solusinya adalah dengan menggunakan cookie bernama berbeda tergantung pada apakah cookie tersebut untuk situs http atau situs https, dan untuk menamai mereka khusus untuk aplikasi Anda. Sebuah __Secure-awalan menunjukkan bahwa cookie harus benar-benar aman, dan juga merupakan praktik yang baik karena aman dan tidak aman tidak akan bertabrakan. Ada manfaat lainnya untuk awalan juga.

Menggunakan /etc/hostsdomain yang berbeda untuk akses https vs. http akan bekerja juga, tetapi satu https://localhostkunjungan tidak disengaja akan mencegah cookie dengan nama yang sama bekerja di http://localhostsitus - jadi ini bukan solusi yang baik.

Saya telah mengajukan laporan bug Chrome .

Vaughan
sumber
0

document.cookie = valuename + "=" + value + ";" + expires + "; domain =; path = /";

ini "domain =; path = /"; akan mengambil domain dinamis karena cookie-nya akan berfungsi di subdomain. jika Anda ingin menguji di localhost itu akan berfungsi

Abhishek SInha
sumber
0

Tidak ada jawaban di sini yang berfungsi untuk saya. Saya memperbaikinya dengan meletakkan PHP saya sebagai hal pertama di halaman.

Seperti tajuk lainnya, cookie harus dikirim sebelum output apa pun dari skrip Anda (ini adalah batasan protokol). Ini mengharuskan Anda melakukan panggilan ke fungsi ini sebelum output apa pun, termasuk dan tag serta spasi putih apa pun.

Dari http://php.net/manual/en/function.setcookie.php

john ktejik
sumber
yang tidak ada hubungannya dengan masalah ini, itu tidak membuat kesalahan dengan mengirimkan output lain sebelum header
Marnes
0

Saya sedang bermain-main sedikit.

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/

berfungsi di Firefox dan Chrome mulai hari ini. Namun, saya tidak menemukan cara untuk membuatnya bekerja dengan ikal. Saya mencoba Host-Header dan --resolve, tidak berhasil, bantuan apa pun dihargai.

Namun, ini berfungsi dalam ikal, jika saya set ke

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/

sebagai gantinya. (Yang tidak berfungsi dengan Firefox.)

Micha
sumber
0

Detail penting lainnya, yang kedaluwarsa = harus menggunakan format waktu tanggal berikut: Wdy, DD-Mon-YYYY HH: MM: SS GMT ( RFC6265 - Bagian 4.1.1 ).

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/
Tralamazza
sumber
5
-1 Spesifikasi saat ini untuk cookie adalah RFC 6265, tools.ietf.org/html/rfc6265 , yang menyatakan secara eksplisit bahwa tahun 4-digit diperbolehkan. Maka itu adalah ide yang buruk untuk menggunakan tahun 2-digit, di mana browser yang berbeda akan menafsirkan secara berbeda.
sleske
Benar. Ref RFC6265 bagian 4.1.1
Zen Cart
4
Benar, tetapi kembali pada Juni 2011 saya tidak menemukan RFC ini. Jadi, sementara info ini sekarang salah, kembali ketika saya menulisnya tidak.
Tralamazza
4
Jangan menganggapnya sebagai hal kecil, segalanya berubah dan kita semua perlu membantu memastikan bahwa jawaban tetap terkini. Cukup perbarui jawaban Anda dengan informasi terbaru yang @sleske berikan kepada Anda dan berterima kasih atas bantuannya.
Matius Purdon
0

Setelah banyak bereksperimen dan membaca berbagai posting, ini berhasil. Saya dapat mengatur beberapa cookie, membacanya kembali dan mengatur waktu negatif dan menghapusnya.

func addCookie(w http.ResponseWriter, name string, value string) {
    expire := time.Now().AddDate(0, 0, 1)
    cookie := http.Cookie{
       Name:    name,
       Value:   value,
       Expires: expire,
       Domain:  ".localhost",
       Path:    "/",
    }
    http.SetCookie(w, &cookie)
}
Saied
sumber
0

Satu-satunya hal yang berhasil bagi saya adalah mengatur Path=/cookie.

Selain itu, nilai default atribut path tampaknya berbeda dari peramban ke peramban meskipun saya hanya menguji dua di antaranya (Firefox dan Chrome).

Chrome mencoba mengatur cookie apa adanya; jika pathatribut dihilangkan dalam Set-Cookieheader maka itu tidak akan disimpan dan diabaikan.

Namun, Firefox menyimpan cookie bahkan tanpa pathatribut eksplisit . Itu hanya mengaturnya dengan jalur yang diminta; url permintaan saya adalah /api/v1/usersdan jalur disetel /api/v1secara otomatis.

Pokoknya, kedua browser berfungsi ketika pathdisetel ke /bahkan tanpa domain eksplisit, yaitu Domain=localhostatau sesuatu. Jadi ada beberapa perbedaan dalam cara masing-masing browser menangani cookie.

이준형
sumber