web-dev-qa-db-fra.com

Cookies sur localhost avec domaine explicite

Je dois manquer quelque chose de base sur les cookies. Sur localhost, lorsque je mets un cookie côté serveur et spécifient le domaine explicitement comme localhost (ou .localhost). le cookie ne semble pas être accepté par certains navigateurs.

Firefox 3.5: J'ai vérifié la requête HTTP dans Firebug. Ce que je vois c'est:

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

ou (quand je mets le domaine à .localhost):

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

Dans les deux cas, le cookie n'est pas stocké.

IE8: Je n’ai utilisé aucun outil supplémentaire, mais le cookie ne semble pas aussi bien être stocké, car il n’est pas renvoyé dans les requêtes suivantes.

Opera 9.64: localhost et .localhost work, mais lorsque je vérifie la liste des cookies dans Préférences, le domaine est défini sur localhost.local, même s’il est répertorié sous localhost (dans le groupe de listes).

Safari 4: localhost et .localhost work, mais ils sont toujours répertoriés en tant que .localhost dans Préférences. D'autre part, un cookie sans domaine explicite, affiché uniquement comme hôte local (pas de point).

Quel est le problème avec localhost? En raison d'un tel nombre d'incohérences, il doit exister des règles spéciales concernant localhost. En outre, je ne comprends pas très bien pourquoi les domaines doivent être précédés d’un point. La RFC 2109 indique explicitement que: 

La valeur de l'attribut Domaine ne contient pas de points incorporés ou n'en contient pas commencez par un point.

Pourquoi? Le document indique qu'il doit faire quelque chose avec la sécurité. Je dois admettre que je n'ai pas lu l'intégralité de la spécification (peut le faire plus tard), mais cela semble un peu étrange. Sur cette base, configurer des cookies sur localhost serait impossible.

156
Jan Zich

De par leur conception, les noms de domaine doivent comporter au moins deux points. sinon, le navigateur les considérera comme non valides. (Voir la référence sur http://curl.haxx.se/rfc/cookie_spec.html )

Lorsque vous travaillez sur localhost, le domaine de cookie doit être entièrement omis. Il ne suffit pas de le régler sur "" ou NULL ou FALSE au lieu de "localhost".

Pour PHP, voir les commentaires sur http://php.net/manual/en/function.setcookie.php#73107 .

Si vous utilisez l'API Java Servlet, n'appelez pas du tout la méthode cookie.setDomain("...").

201
Ralph Buchfelder

Je suis globalement d’accord avec @Ralph Buchfelder, mais voici une analyse approfondie de ceci, expérimentalement, lorsque je tente de reproduire un système avec plusieurs sous-domaines (tels que example.com, fr.example.com, de.example.com) sur ma machine locale ( OS X/Apache/Chrome | Firefox).

J'ai édité/etc/hosts pour pointer des sous-domaines imaginaires vers 127.0.0.1:

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

Si je travaille sur fr.localexample.com et que je laisse le paramètre de domaine vide, le cookie est correctement stocké pour fr.localexample.com, mais n'est pas visible dans les autres sous-domaines.

Si j'utilise un domaine de ".localexample.com", le cookie est correctement stocké pour fr.localexample.com et est visible dans les autres sous-domaines.

Si j'utilise un domaine de "localexample.com" ou lorsque j'essaie un domaine de "localexample" ou "localhost" uniquement, le cookie n'est pas enregistré.

Si j'utilise un domaine de "fr.localexample.com" ou ".fr.localexample.com", le cookie est correctement stocké pour fr.localexample.com et est (correctement) invisible dans les autres sous-domaines.

Ainsi, l'exigence selon laquelle vous avez besoin d'au moins deux points dans le domaine semble être correcte, même si je ne vois pas pourquoi.

Si quelqu'un veut l'essayer, voici un code utile:

<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>
28
xgretsch

localhost: Vous pouvez utiliser: domain: ".app.localhost" et cela fonctionnera. Le paramètre 'domain' nécessite 1 ou plusieurs points dans le nom de domaine pour configurer les cookies. Ensuite, vous pouvez avoir des sessions fonctionnant sur plusieurs sous-domaines tels que: api.app.localhost:3000.

23
AmpT

Lorsqu'un cookie est défini avec un domaine explicite de "localhost" comme suit ...

Set-Cookie: nom = valeur; domain = localhost; expire = jeu., 16 juillet 2009 21:25:05 GMT; chemin = /

... alors les navigateurs l'ignorent car il n'inclut pas au moins deux périodes et ne fait pas partie des sept domaines de premier niveau spécialement gérés

... les domaines doivent comporter au moins deux (2) ou trois (3) périodes pour que empêchez les domaines de la forme: ".com", ".edu" et "va.us". N'importe quel domaine qui échoue dans l’un des sept domaines de premier niveau spéciaux répertoriés ci-dessous ne nécessitent que deux périodes. Tout autre domaine nécessite au moins Trois. Les sept domaines de premier niveau spéciaux sont: "COM", "EDU", "NET", "ORG", "GOV", "MIL" et "INT".

Notez que le nombre de périodes ci-dessus suppose probablement qu'une période de début est requise. Cette période est cependant ignorée par les navigateurs modernes et elle devrait probablement se lire ...

au moins un (1) ou deux (2) périodes

Notez que la valeur par défaut de l'attribut de domaine est le nom d'hôte du serveur qui a généré la réponse du cookie .

Donc, une solution de contournement pour les cookies qui ne sont pas définis pour localhost consiste simplement à ne pas spécifier d'attribut de domaine et à laisser le navigateur utiliser la valeur par défaut - cela ne semble pas avoir les mêmes contraintes qu'une valeur explicite dans l'attribut de domaine.

10
Scott Munro

Résultats que j'avais variés par navigateur. 

Chrome-127.0.0.1 fonctionnait, mais localhost .localhost et "" ne fonctionnait pas . Firefox-.localhost fonctionnait, mais localhost, 127.0.0.1 et "" ne fonctionnait pas.

Ne pas avoir testé dans Opera, IE ou Safari

3
user631063

J'ai passé beaucoup de temps à résoudre ce problème moi-même.

Utiliser PHP, et rien sur cette page n'a fonctionné pour moi. J'ai finalement réalisé dans mon code que le paramètre "secure" de la session de PHP session_set_cookie_params () était toujours défini sur TRUE. 

Comme je ne visitais pas localhost avec https, mon navigateur n'accepterait jamais le cookie. J'ai donc modifié cette partie de mon code pour définir de manière conditionnelle le paramètre 'secure' basé sur $ _SERVER ['HTTP_Host'] étant 'localhost' ou non. Travaille bien maintenant.

J'espère que ça aidera quelqu'un.

2
James Jacobson

Aucune des solutions suggérées ne fonctionnait pour moi - le définir sur null, false, ajouter deux points, etc. - ne fonctionnait pas. 

En fin de compte, je viens de supprimer le domaine du cookie s'il s'agit de localhost et que cela fonctionne maintenant pour moi dans Chrome 38 .

Code précédent (n'a pas fonctionné):

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

Nouveau code (fonctionne maintenant):

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

vous pouvez utiliser localhost.org ou plutôt .localhost.org, il sera toujours résolu en 127.0.0.1

1
qoomon

J'ai eu beaucoup plus de chance de tester localement en utilisant 127.0.0.1 comme domaine. Je ne sais pas pourquoi, mais j'avais des résultats mitigés avec localhost et .localhost, etc.

1
toby

Il semble y avoir un problème lorsque vous utilisez https://<local-domain>, puis http://<local-domain>. Le site http:// n'envoie pas de cookies avec les demandes après que le site https:// les ait configurés. Forcer le rechargement et effacer le cache n'aide pas. Seul le nettoyage manuel des cookies fonctionne. De plus, si je les efface sur la page https://, la page http:// recommence à fonctionner.

Cela semble lié aux "cookies sécurisés stricts". Bonne explication ici . Il a été publié dans Chrome 58 le 2017-04-19.

Il semblerait que Chrome enregistre effectivement les cookies sécurisés et non sécurisés, car il affiche les cookies appropriés en fonction du protocole de la page lorsque vous cliquez sur l'icône de la barre d'adresse.

Mais Developer tools > Application > Cookies n’affichera pas de cookie non sécurisé s’il existe un cookie sécurisé du même nom pour le même domaine, et n’enverra pas le cookie non sécurisé avec les demandes. Cela ressemble à un bogue de Chrome ou, si ce problème est prévu, il devrait exister un moyen d'afficher les cookies sécurisés sur une page http et d'indiquer qu'ils sont remplacés.

La solution de contournement consiste à utiliser différents cookies nommés, en fonction de leur nature, pour un site http ou https, et pour les nommer de manière spécifique à votre application. Un préfixe __Secure- indique que le cookie doit être strictement sécurisé. Il s'agit également d'une bonne pratique, car sécurisé et non sécurisé n'entrera pas en collision. Il y a d'autres avantages aux préfixes aussi.

L'utilisation de différents domaines /etc/hosts pour l'accès https et http pourrait également fonctionner, mais une visite accidentelle de https://localhost empêchera tout cookie du même nom de fonctionner sur les sites http://localhost. Il ne s'agit donc pas d'une solution de rechange efficace.

J'ai déposé un rapport de bogue Chrome .

1
vaughan

Je jouais un peu. 

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

fonctionne dans Firefox et Chrome à partir d'aujourd'hui. Cependant, je n'ai pas trouvé le moyen de le faire fonctionner avec curl. J'ai essayé Host-Header et --resolve, aucune chance, aucune aide appréciée.

Cependant, cela fonctionne en boucle, si je le règle sur

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

au lieu. (Ce qui ne fonctionne pas avec Firefox.)

0
Micha

document.cookie = nom de la valeur + "=" + valeur + ";" + expire + "; domaine =; chemin = /";

ce "domaine =; chemin = /"; prendra domaine dynamique que son cookie fonctionnera dans le sous-domaine . si vous voulez tester dans localhost cela fonctionnera

0
Abhishek SInha

Il existe un problème relatif à Chromium ouvert depuis 2011 , selon lequel, si vous définissez explicitement le domaine comme "localhost", vous devez le définir comme suit: false ou undefined.

0
Bruno Peres

Un autre détail important, expires = devrait utiliser le format d'heure date suivant: Wdy, JJ-Lun-AAAA HH: MM: SS GMT} _ ( RFC6265 - Section 4.1.1 ) .

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/
0
Tralamazza

Si vous définissez un cookie à partir d'un autre domaine (c'est-à-dire que vous définissez le cookie en effectuant une demande d'origine XHR croisée), vous devez vous assurer que vous définissez l'attribut withCredentials sur true dans XMLHttpRequest que vous utilisez pour extraire le cookie comme décrit ici

0
Aidan Ewen

J'ai eu le même problème et je l'ai corrigé en mettant 2 points dans le nom du cookie lui-même sans spécifier de domaine.

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

Aucune des réponses ici n'a fonctionné pour moi. Je l'ai corrigé en plaçant mon PHP comme la toute première chose dans la page.

Comme les autres en-têtes, les cookies doivent être envoyés avant toute sortie de votre script (il s'agit d'une restriction de protocole). Cela nécessite que vous appeliez cette fonction avant toute sortie, y compris les balises et les espaces.

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

0
john ktejik