Cookies auf localhost mit expliziter Domain

191

Mir muss etwas Grundlegendes über Cookies fehlen. Auf localhost, wenn ich auf der Serverseite ein Cookie setze und die Domäne explizit als localhost (oder .localhost) spezifiziere. Das Cookie scheint von einigen Browsern nicht akzeptiert zu werden.

Firefox 3.5: Ich habe die HTTP-Anfrage in Firebug überprüft. Was ich sehe ist:

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

oder (wenn ich die Domain auf .localhost setze):

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

In beiden Fällen wird das Cookie nicht gespeichert.

IE8: Ich habe kein zusätzliches Tool verwendet, aber das Cookie scheint nicht ebenfalls gespeichert zu sein, da es bei nachfolgenden Anforderungen nicht zurückgesendet wird.

Opera 9.64: Sowohl localhost als auch .localhost funktionieren , aber wenn ich die Liste der Cookies in den Einstellungen überprüfe, wird die Domäne auf localhost.local festgelegt, obwohl sie unter localhost (in der Listengruppierung) aufgeführt ist.

Safari 4: Sowohl localhost als auch .localhost funktionieren , werden jedoch in den Einstellungen immer als .localhost aufgeführt. Auf der anderen Seite ein Cookie ohne explizite Domain, das nur als localhost (kein Punkt) angezeigt wird.

Was ist das Problem mit localhost? Aufgrund einer solchen Anzahl von Inkonsistenzen müssen einige spezielle Regeln für localhost gelten. Außerdem ist mir nicht ganz klar, warum Domains ein Punkt vorangestellt werden muss. In RFC 2109 heißt es ausdrücklich:

Der Wert für das Domain-Attribut enthält keine eingebetteten Punkte oder beginnt nicht mit einem Punkt.

Warum? Das Dokument zeigt an, dass es etwas mit Sicherheit zu tun hat. Ich muss zugeben, dass ich nicht die gesamte Spezifikation gelesen habe (kann es später tun), aber es klingt ein bisschen seltsam. Auf dieser Grundlage wäre es unmöglich, Cookies auf localhost zu setzen.

Jan Zich
quelle
13
6 Jahre alter Thread und das ist immer noch ein Problem. Ich verwende Chrome v40. Siehe hier .
Gaui
5
Chrome 43 ... immer noch ein Fehler.
Evan Carroll
4
Chrome 54 hier, NICHT gelöst
Vahid Amiri
6
Chrome 73 .. steht immer noch vor dem gleichen Problem. :(
Code_Crash
2
Könnte jemand das lösen? Immer noch vor dem gleichen s *** .. siehe diese SO Antwort
Bonjour123

Antworten:

235

Domain-Namen müssen standardmäßig mindestens zwei Punkte haben. Andernfalls betrachtet der Browser sie als ungültig. (Siehe Referenz unter http://curl.haxx.se/rfc/cookie_spec.html )

Bei der Arbeit localhostmuss die Cookie-Domain vollständig weggelassen werden. Es reicht nicht aus , es nur auf ""oder NULLoder FALSEanstelle von "localhost"einzustellen.

Informationen zu PHP finden Sie in den Kommentaren unter http://php.net/manual/en/function.setcookie.php#73107 .

Wenn Sie mit der Java-Servlet-API arbeiten, rufen Sie die cookie.setDomain("...")Methode überhaupt nicht auf.

Ralph Buchfelder
quelle
93
Ich bin mir nicht sicher, warum alle dies + 1 tun. Ich habe die Domain des Cookies auf null oder false oder eine leere Zeichenfolge gesetzt und es wird immer noch nicht gespeichert, wenn auf localhost.
Justin
5
Ich sehe in RFC6265 nirgendwo etwas über die beiden Punkte in der Domäne: tools.ietf.org/html/rfc6265#section-5.2.3 .Net sagt, dass es für alle Hosts in Ihrer lokalen Domäne auf ".local" gesetzt ist. Das scheint im Einklang mit Opera / Safari msdn.microsoft.com/en-us/library/ckch3yd2.aspx
MandoMando
9
@ Justin: Hm, wahrscheinlich müssen Sie den Domain=Parameter beim Setzen des Cookies komplett weglassen . Wenn Sie die Domäne nur auf null oder leer setzen, sendet Ihr Framework möglicherweise den Domain=Parameter mit diesem Wert, anstatt ihn wegzulassen. Überprüfen Sie mit zB Firebug.
Sleske
2
@ Ralph, eine Million danke, dieses Ding hat mich ein paar Stunden lang verrückt gemacht. Hoffentlich funktioniert das Setzen der Domain auf null (ich bin in einem .NET-Server-Stack) wie ein Zauber.
Xose Lluis
4
Dies ist etwas schlecht formuliert. "Auf null oder falsche oder leere Zeichenfolge setzen" sollte lauten: "Den 'Domain'-Teil des Cookies überhaupt nicht setzen." Die Verwendung eines einfachen Tests zum vollständigen ((domain && domain !== "localhost") ? ";domain="+domain : "")
Auslassen
33

Ich stimme @Ralph Buchfelder im Großen und Ganzen zu, aber hier ist eine Verstärkung davon durch Experimente, wenn versucht wird, ein System mit mehreren Subdomänen (wie example.com, fr.example.com, de.example.com) auf meinem lokalen Computer zu replizieren ( OS X / Apache / Chrome | Firefox).

Ich habe / etc / hosts bearbeitet, um einige imaginäre Subdomains auf 127.0.0.1 zu verweisen:

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

Wenn ich an fr.localexample.com arbeite und den Domain-Parameter weglasse, wird das Cookie für fr.localexample.com korrekt gespeichert, ist aber in den anderen Subdomains nicht sichtbar.

Wenn ich eine Domain von ".localexample.com" verwende, wird das Cookie für fr.localexample.com korrekt gespeichert und ist in anderen Subdomains sichtbar.

Wenn ich eine Domain von "localexample.com" verwende oder wenn ich eine Domain von "localexample" oder "localhost" versuche, wird das Cookie nicht gespeichert.

Wenn ich eine Domain von "fr.localexample.com" oder ".fr.localexample.com" verwende, wird das Cookie für fr.localexample.com korrekt gespeichert und ist in anderen Subdomains (korrekt) unsichtbar.

Die Anforderung, dass Sie mindestens zwei Punkte in der Domäne benötigen, scheint also korrekt zu sein, obwohl ich nicht verstehen kann, warum dies der Fall sein sollte.

Wenn jemand dies ausprobieren möchte, ist hier ein nützlicher Code:

<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
quelle
30

localhost: Sie können verwenden: domain: ".app.localhost"und es wird funktionieren. Der Parameter 'domain' benötigt 1 oder mehr Punkte im Domainnamen, um Cookies zu setzen. Anschließend können Sitzungen in lokalen Host-Subdomänen ausgeführt werden, z api.app.localhost:3000.

AmpT
quelle
1
Ebenfalls getestet und auf einem node.js-Server mit Express 3.x inexpress.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
AmpT
3
Dies sollte als Antwort ausgewählt werden, wenn Sie lokale Domains verwenden! Das Setzen eines Punktes vor der Subdomain behebt mein Problem.
Foxhoundn
1
Woher kommt also dieses Voranstellen des .app.Kommens? Ist es Teil einer SPEC? Und gilt es für alle nicht konformen Domänen (diejenigen ohne zwei Punkte)? Funktioniert dies auch mit alten Browsern? : ^)
user2173353
Oh ... ich verstehe jetzt ... Es ist nur ein Trick, die Browser zu täuschen. OK.
user2173353
14

Wenn ein Cookie mit der expliziten Domäne 'localhost' wie folgt gesetzt wird ...

Set-Cookie: Name = Wert; domain = localhost ; läuft ab = Do, 16.07.2009 21:25:05 GMT; Pfad = /

... dann ignorieren Browser es, weil es nicht mindestens zwei Punkte enthält und keine von sieben speziell behandelten Top-Level-Domains ist .

... Domains müssen mindestens zwei (2) oder drei (3) Punkte enthalten, um Domains der Form ".com", ".edu" und "va.us" zu verhindern. Jede Domain, die innerhalb einer der sieben unten aufgeführten speziellen Top-Level-Domains ausfällt, benötigt nur zwei Zeiträume. Für jede andere Domain sind mindestens drei erforderlich. Die sieben speziellen Top-Level-Domains sind: "COM", "EDU", "NET", "ORG", "GOV", "MIL" und "INT".

Beachten Sie, dass die Anzahl der oben genannten Perioden wahrscheinlich davon ausgeht, dass eine führende Periode erforderlich ist. Dieser Zeitraum wird jedoch in modernen Browsern ignoriert und sollte wahrscheinlich ...

mindestens eine (1) oder zwei (2) Perioden

Beachten Sie, dass der Standardwert für das Domänenattribut der Hostname des Servers ist, der die Cookie-Antwort generiert hat .

So eine Abhilfe für Cookies für localhost nicht gesetzt sind , ist einfach kein Domain - Attribut angeben und der Browser den Standardwert verwenden lassen - dies scheint nicht die gleichen Einschränkungen zu haben , dass ein expliziter Wert in dem Domäne - Attribute.

Scott Munro
quelle
Ich habe kein DV gemacht, aber ich vermute, der Grund, warum andere es getan haben, ist, dass Ihre Antwort nicht wirklich viel Wert hinzufügt. Die Anforderung von zwei Zeiträumen und das Leerlassen des Domänenattributs wurden beide in anderen Antworten erörtert. Außerdem scheint das, was Sie über eine Top-Level-Domain hinzugefügt haben, falsch zu sein. Nach meiner Erfahrung ist das keine Voraussetzung.
TTT
@TTT Sie sind sich nicht sicher, ob Sie in meiner Antwort zu dem Punkt gekommen sind, an dem ich sage, dass es je nach TLD mindestens ein oder zwei Perioden sein sollte, da führende Perioden ignoriert werden? Daher habe ich einige Hintergrundinformationen zu dem Problem bereitgestellt und einen Punkt hinzugefügt, von dem ich glaube, dass er nicht an anderer Stelle behandelt wird. Die Regeln für eine explizite Domäne unterscheiden sich von der, die der Browser standardmäßig verwendet. Scheint, als würde es mir einen Mehrwert bringen.
Scott Munro
1
Wenn Sie die Domain null lassen (überhaupt nicht festlegen), behält Chrome das Cookie für localhost NICHT bei. Es ignoriert es immer noch. Beachten Sie, dass dies nur für "permanente" Cookies gilt (solche, die ein Ablaufdatum festlegen), da es sich um "Sitzungscookies" für localhost handelt (solche, die kein Ablaufdatum festlegen).
Triynko
3

Ergebnisse hatte ich je nach Browser variiert.

Chrome-127.0.0.1 funktionierte, localhost .localhost und "" jedoch nicht. Firefox- .localhost funktionierte, localhost 127.0.0.1 und "" jedoch nicht.

Habe nicht in Opera, IE oder Safari getestet


quelle
3
Gerade mit Chrome V.22.0.1229.94 m getestet: Das Setzen eines Cookies für localhost ohne Angabe eines Domain=Parameters funktioniert. Domain=funktioniert auch, funktioniert aber Domain=localhostnicht.
Sleske
3

Ich habe viel Zeit damit verbracht, dieses Problem selbst zu beheben.

Die Verwendung von PHP und Nothing auf dieser Seite hat bei mir funktioniert. In meinem Code wurde mir schließlich klar, dass der 'sichere' Parameter für PHPs session_set_cookie_params () immer auf TRUE gesetzt wurde.

Da ich localhost nicht mit https besuchte, akzeptierte mein Browser das Cookie niemals. Also habe ich diesen Teil meines Codes geändert, um den 'sicheren' Parameter basierend darauf festzulegen, dass $ _SERVER ['HTTP_HOST'] 'localhost' ist oder nicht. Funktioniert jetzt gut.

Ich hoffe das hilft jemandem.

James Jacobson
quelle
2

Wenn Sie ein Cookie aus einer anderen Domäne setzen (dh Sie setzen das Cookie, indem Sie eine XHR-Cross-Origin-Anfrage stellen), müssen Sie sicherstellen, dass Sie das withCredentialsAttribut in der XMLHttpRequest, mit der Sie das Cookie abrufen, wie hier beschrieben, auf true setzen

Aidan Ewen
quelle
ja auch damit. Es funktioniert immer noch nicht mit domänenübergreifenden Anforderungen. Browser - Safari, IE 11
Rohit Kumar
2

Sie können verwenden localhost.orgoder vielmehr wird .localhost.orges immer zu lösen127.0.0.1

Qoomon
quelle
1

Ich hatte viel mehr Glück beim lokalen Testen mit 127.0.0.1 als Domain. Ich bin mir nicht sicher warum, aber ich hatte gemischte Ergebnisse mit localhost und .localhost usw.

toby
quelle
1

Keine der vorgeschlagenen Korrekturen hat bei mir funktioniert - Setzen auf Null, Falsch, Hinzufügen von zwei Punkten usw. - hat nicht funktioniert.

Am Ende habe ich gerade die Domain aus dem Cookie entfernt, wenn es sich um localhost handelt, und das funktioniert jetzt in Chrome 38 für mich .

Vorheriger Code (hat nicht funktioniert):

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

Neuer Code (funktioniert jetzt):

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

Ich hatte das gleiche Problem und habe es behoben, indem ich 2 Punkte in den Cookie-Namen selbst eingefügt habe, ohne eine Domain anzugeben.

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

Es scheint ein Problem zu geben, wenn Sie https://<local-domain>und dann verwenden http://<local-domain>. Die http://Site sendet keine Cookies mit Anfragen, nachdem die https://Site diese gesetzt hat. Das Neuladen erzwingen und den Cache leeren hilft nicht. Nur das manuelle Löschen von Cookies funktioniert. Wenn ich sie auf der Seite lösche, funktioniert die https://Seite http://wieder.

Scheint mit "Strict Secure Cookies" verwandt zu sein. Gute Erklärung hier . Es wurde in Chrome 58 am 2017-04-19 veröffentlicht.

Es sieht so aus, als würde Chrome tatsächlich sowohl sichere als auch nicht sichere Cookies aufzeichnen, da beim Klicken auf das Adressleistensymbol je nach Protokoll der Seite die richtigen Cookies angezeigt werden.

Es Developer tools > Application > Cookieswird jedoch kein nicht sicheres Cookie angezeigt, wenn es ein sicheres Cookie mit demselben Namen für dieselbe Domain gibt, und es wird auch kein nicht sicheres Cookie mit Anfragen gesendet. Dies scheint ein Chrome-Fehler zu sein. Wenn dieses Verhalten erwartet wird, sollte es eine Möglichkeit geben, die sicheren Cookies auf einer httpSeite anzuzeigen und anzuzeigen , dass sie überschrieben werden.

Problemumgehung: Verwenden Sie Cookies mit unterschiedlichen Namen, je nachdem, ob sie für eine http- oder eine https-Site bestimmt sind, und benennen Sie sie spezifisch für Ihre App. Ein __Secure-Präfix gibt an, dass das Cookie streng sicher sein sollte, und ist auch eine gute Vorgehensweise, da sicher und nicht sicher nicht kollidieren. Es gibt andere Vorteile auch zu Präfixe.

Die Verwendung unterschiedlicher /etc/hostsDomänen für den Zugriff auf https und http würde ebenfalls funktionieren, aber ein versehentlicher https://localhostBesuch verhindert, dass Cookies mit demselben Namen auf http://localhostWebsites funktionieren. Dies ist also keine gute Problemumgehung.

Ich habe eine eingereicht Chrome-Fehlerbericht .

Vaughan
quelle
0

document.cookie = Wertname + "=" + Wert + ";" + läuft ab + "; domain =; path = /";

diese "domain =; path = /"; nimmt eine dynamische Domain an, da das Cookie in der Subdomain funktioniert. Wenn Sie in localhost testen möchten, wird es funktionieren

Abhishek SInha
quelle
0

Keine der Antworten hier hat bei mir funktioniert. Ich habe es behoben, indem ich mein PHP als erstes auf die Seite gesetzt habe.

Wie bei anderen Headern müssen Cookies vor jeder Ausgabe Ihres Skripts gesendet werden (dies ist eine Protokollbeschränkung). Dies erfordert, dass Sie diese Funktion vor jeder Ausgabe aufrufen, einschließlich und Tags sowie vor Leerzeichen.

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

John Ktejik
quelle
das hat aber nichts mit dem Problem zu tun, das macht einfach nicht den Fehler, eine andere Ausgabe vor den Headern zu senden
Marnes
0

Ich habe ein bisschen rumgespielt.

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

funktioniert ab heute in Firefox und Chrome. Ich habe jedoch keinen Weg gefunden, es mit Curl zum Laufen zu bringen. Ich habe Host-Header ausprobiert und --resolve, kein Glück, jede Hilfe geschätzt.

Es funktioniert jedoch in Curl, wenn ich es auf setze

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

stattdessen. (Was mit Firefox nicht funktioniert.)

Micha
quelle
0

Ein weiteres wichtiges Detail, das expires = sollte das folgende Datums- / Uhrzeitformat verwenden: Wdy, TT-Mo-JJJJ HH: MM: SS GMT ( RFC6265 - Abschnitt 4.1.1 ).

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/
Tralamazza
quelle
5
-1 Die aktuelle Spezifikation für Cookies ist RFC 6265, tools.ietf.org/html/rfc6265 , in der ausdrücklich angegeben ist, dass 4-stellige Jahre zulässig sind. Daher ist es eine schlechte Idee, zweistellige Jahre zu verwenden, die von verschiedenen Browsern unterschiedlich interpretiert werden.
Sleske
Richtig. Ref RFC6265 Abschnitt 4.1.1
Zen Cart
4
Richtig, aber im Juni 2011 habe ich diesen RFC nicht gefunden. Während diese Informationen jetzt falsch sind, war es damals, als ich sie schrieb, nicht so.
Tralamazza
4
Nehmen Sie es nicht als geringfügig, die Dinge ändern sich und wir alle müssen dazu beitragen, dass die Antworten aktuell bleiben. Aktualisieren Sie einfach Ihre Antwort mit den neuesten Informationen, die @sleske Ihnen gegeben hat, und danken Sie ihm für seine Hilfe.
Matthew Purdon
0

Nach vielem Experimentieren und Lesen verschiedener Beiträge funktionierte dies. Ich könnte mehrere Cookies setzen, sie zurücklesen und die Zeit negativ einstellen und sie löschen.

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
quelle
0

Das einzige, was für mich funktioniert hat, war, Path=/den Cookie zu setzen.

Darüber hinaus scheint sich der Standardwert eines Pfadattributs von Browser zu Browser zu unterscheiden, obwohl ich nur zwei davon getestet habe (Firefox und Chrome).

Chrome versucht, ein Cookie so zu setzen, wie es ist. Wenn das pathAttribut im Set-CookieHeader weggelassen wird, wird es nicht gespeichert und ignoriert.

Firefox speichert jedoch ein Cookie auch ohne explizites pathAttribut. Es wird nur der angeforderte Pfad festgelegt. Meine Anforderungs-URL war /api/v1/usersund der Pfad wurde /api/v1automatisch festgelegt.

Wie auch immer, beide Browser funktionierten, wenn pathsie /auch ohne explizite Domain eingestellt waren, dh Domain=localhostoder so. Es gibt also einige Unterschiede in der Art und Weise, wie jeder Browser mit Cookies umgeht.

이준형
quelle