Cookies на localhost с явным доменом

Я, должно быть, пропустил некоторые основные вещи о печенье. На localhost, когда я устанавливаю cookie на стороне сервера и укажите домен явно как localhost (или .локальный хост.) печенье не воспринимаются некоторыми браузерами.

Firefox 3.5: Я проверил HTTP-запрос в Firebug. Вот что я вижу:--5-->

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

или (когда я поставил домен .localhost):

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

в любом случае, cookie не является на хранении.

IE8: Я не использовал никакого дополнительного инструмента, но cookie, похоже, не хранится, потому что он не отправляется обратно в последующих запросах.

Opera 9.64: как localhost, так и .имя localhost работа, но когда я проверяю список куки в настройках, домен устанавливается в localhost.локальный, даже если он указан в localhost (в группе списков).

Safari 4: как localhost, так и .имя localhost работа, но они всегда указаны в качестве .localhost в настройках. С другой стороны, файл cookie без явного домена отображается как localhost (без точки).

в чем проблема с localhost? Из-за такого количества несоответствий должны быть некоторые специальные правила, касающиеся localhost. Кроме того, мне не совсем понятно, почему домены должны иметь префикс точки? RFC 2109 явно заявляет, что:

значение Атрибут домена не содержит встроенных точек или не содержит начните с точки.

почему? Документ указывает, что он должен что-то делать с безопасностью. Я должен признать, что я не прочитал всю спецификацию (может быть, позже), но это звучит немного странно. Исходя из этого, установка cookies на localhost будет невозможна.

15 ответов


по дизайну доменные имена должны иметь не менее двух точек; в противном случае браузер будет считать их недействительными. (См. ссылку на http://curl.haxx.se/rfc/cookie_spec.html)

работая на localhost, домен cookie должен быть полностью опущен. Просто установите его в "" или NULL или FALSE вместо "localhost" не хватает.

для PHP см. комментарии кhttp://php.net/manual/en/function.setcookie.php#73107.

если работая с API сервлета Java, не вызывайте cookie.setDomain("...") метод на всех.


Я в целом согласен с @Ralph Buchfelder, но вот некоторое усиление этого, экспериментом при попытке реплицировать систему с несколькими поддоменами (такими как example.com, fr.example.com, de.example.com) на моей локальной машине (OS X / Apache|Chrome / Firefox).

я отредактировал/etc / hosts, чтобы указать некоторые воображаемые поддомены в 127.0.0.1:

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

Если я работаю дальше fr.localexample.com и я оставляю параметр домена, cookie хранится правильно для fr.localexample.com, но не видно в других поддоменах.

Если я использую домен ".localexample.com", cookie хранится правильно для fr.localexample.com и is виден в других поддоменах.

Если я использую домен "localexample.com", или когда я пробовал домен только "localexample" или "localhost", cookie не сохранялся.

Если я использую домен "fr.localexample.com" или ".fr.localexample.com", печенье сохранено правильно для fr.localexample.com и (правильно) невидим в других поддоменах.

таким образом, требование, что вам нужно по крайней мере две точки в домене, кажется правильным, хотя я не вижу, почему это должно быть так.

Если кто-то хочет попробовать это, вот полезный код:

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

localhost: вы можете использовать: domain: ".app.localhost" и это сработает. The параметр "домен" требует 1 или более точек в доменном имени для установки cookies. Затем вы можете иметь сеансы, работающие через поддомены localhost, такие как:api.app.localhost:3000.


когда cookie установлен с явным доменом "localhost" следующим образом...

Set-Cookie: name=значение; домен=localhost; истекает=Чт, 16-июл-2009 21:25: 05 GMT; путь=/

...тогда браузеры игнорируют его, потому что он не включает по крайней мере два периода и не является одним из семи специально обработанных доменов верхнего уровня.

...домены должны иметь не менее двух (2) или трех (3) периодов по их запретить Домены вида: ".com",".edu", и " va.мы". Любой домен это не удается в одном из семи специальных доменов верхнего уровня, перечисленных ниже требуется только два периода. Любой другой домен требует, по крайней мере три. Семь специальных доменов верхнего уровня: "COM", "EDU", " NET", "ORG", "GOV", "MIL"и " INT".

обратите внимание, что количество периодов выше, вероятно, предполагает, что требуется начальный период. Однако этот период игнорируется в современных браузерах и, наверное,стоит прочитать...

по крайней мере один (1) или два (2) периода

обратите внимание, что значение по умолчанию для атрибута домена:имя хоста сервера, который сгенерировал ответ cookie.

Так обходной путь для cookies не устанавливается для localhost, чтобы просто не указать атрибут домена и пусть браузер использует значение по умолчанию - это не похоже на то же самое ограничения, которые делает явное значение в атрибуте домена.


результаты, которые я варьировал в зависимости от браузера.

Chrome-127.0.0.1 работал, но localhost .localhost и "" не. браузер Firefox. -localhost работал, но localhost, 127.0.0.1 и "" не работали.

не тестировались в Opera, IE или Safari


потратил много времени на устранение этой проблемы сам.

используя PHP, и ничто на этой странице не работало для меня. В конце концов я понял в своем коде, что параметр "secure" для PHP session_set_cookie_params () всегда было установлено значение TRUE.

поскольку я не посещал localhost с https, мой браузер никогда не принимал cookie. Итак, я изменил эту часть своего кода, чтобы условно установить "безопасный" параметр на основе $_SERVER ['HTTP_HOST'] быть "localhost" или нет. Работает хорошо.

надеюсь, это кому-то поможет.


мне гораздо больше повезло тестировать локально, используя 127.0.0.1 в качестве домена. Я не знаю, почему, но у меня были смешанные результаты с localhost и .на localhost и т. д.


ни одно из предложенных исправлений не сработало для меня-установка значения null, false, добавление двух точек и т. д.-не сработало.

в конце концов, я просто удалил домен из cookie, если это localhost, и теперь это работает для меня в Chrome 38.

предыдущий код (не работает):

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

новый код (сейчас работает):

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

документ.cookie = valuename + " = " + value+"; " + истекает+"; домен=;путь=/";

этот " домен=; path=/"; будет принимать динамический домен, поскольку его cookie будет работать в поддомене. если вы хотите протестировать в localhost, он будет работать


ни один из ответов здесь работал для меня. Я исправил это, поставив свой PHP как самое первое на странице.

как и другие заголовки, cookies должны быть отправлены перед любым выходом из вашего скрипта (это ограничение протокола). Это требует, чтобы вы размещали вызовы этой функции до любого вывода, включая и теги, а также любые пробелы.

от http://php.net/manual/en/function.setcookie.php


есть выпуск на Chromium открыт с 2011 года, что если вы явно устанавливаете домен как "localhost", вы должны установить его как false или undefined.


Я немного поиграл.

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

работает в Firefox и Chrome на сегодняшний день. Однако я не нашел способа заставить его работать с curl. Я попробовал Host-Header и -- resolve, не повезло,любая помощь оценена.

однако он работает в curl, если я установил его в

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

вместо. (Который не работает с Firefox.)


еще одна важная деталь, о истекает= использовать следующий формат даты и времени: Wdy, DD-Mon-YYYY HH: MM: SS GMT (RFC6265-раздел 4.1.1).

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

У меня была та же проблема, и я исправил ее, поставив 2 точки в самом имени cookie без указания какого-либо домена.

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

кажется, есть проблема, когда вы используете https://<local-domain> а то http://<local-domain>. The http:// сайт не отправляет cookies с запросами после https:// сайт устанавливает их. Перезагрузка и очистка кэша не помогает. Работает только ручная очистка cookies. Кроме того, если я очищу их от https:// страница, затем http:// страница снова начинает работать.

похоже, связано со "строгими защищенными куки". Хорошее объяснение!--15-->здесь. Это было выпущен в Chrome 58 on 2017-04-19.

похоже, что Chrome на самом деле записывает как безопасные, так и небезопасные куки, поскольку он покажет правильные куки в зависимости от протокола страницы при нажатии на значок адресной строки.

но Developer tools > Application > Cookies не показывать небезопасного печенья, когда есть безопасные cookie для домена, и не будет отправлять небезопасного печенья с любыми запросами. Это похоже на ошибку Chrome, или если такое поведение ожидается, должны быть некоторые способ просмотра защищенных cookies, когда на http страницы и указание на то, что они переопределяются.

обходной путь-использовать разные именованные куки в зависимости от того, являются ли они для http-сайта или https-сайта, и называть их конкретными для вашего приложения. А __Secure- префикс указывает, что файл cookie должен быть строго защищен, а также является хорошей практикой, потому что безопасный и небезопасный не будут сталкиваться. Есть другие преимущества тоже префиксов.

используя разные /etc/hosts домены для https против http-доступа тоже будут работать, но один случайный https://localhost посещение предотвратит любые куки с одинаковыми именами для работы на http://localhost сайты-так что это не хороший обходной путь.

я подал отчет об ошибке Chrome.