带有显式域的localhost上的Cookie

时间:2009-07-15 21:47:55

标签: cookies setcookie

我必须遗漏一些关于cookie的基本知识。在localhost上,当我在服务器端设置cookie时将域明确指定为localhost(或.localhost)。某些浏览器似乎不接受cookie。

Firefox 3.5:我在Firebug中检查了HTTP请求。我看到的是:

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 都工作,但是当我检查“首选项”中的Cookie列表时,即使列出了域,域也会设置为localhost.local在localhost下(在列表分组中)。

Safari 4: localhost和.localhost 都工作,但它们在“首选项”中始终列为.localhost。另一方面,没有显式域的cookie,它只显示为localhost(无点)。

localhost有什么问题?由于存在这么多的不一致,必须有一些涉及localhost的特殊规则。另外,我不完全清楚为什么域名必须以点为前缀? RFC 2109明确声明:

  

Domain属性的值   不包含嵌入点或不包含嵌入点   从一个点开始。

为什么呢?该文件表明它必须对安全做些什么。我不得不承认我没有阅读整个规范(稍后可能会这样做),但听起来有点奇怪。基于此,在localhost上设置cookie是不可能的。

20 个答案:

答案 0 :(得分:209)

按照设计,域名必须至少有两个点;否则浏览器会认为它们无效。 (见http://curl.haxx.se/rfc/cookie_spec.html上的参考资料)

处理localhost时,必须完全省略cookie域。仅将其设置为""NULLFALSE而不是"localhost"是不够的。

对于PHP,请参阅http://php.net/manual/en/function.setcookie.php#73107上的评论。

如果使用Java Servlet API,请不要调用cookie.setDomain("...")方法。

答案 1 :(得分:29)

我对@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并且我保留了domain参数,则cookie会正确存储到fr.localexample.com,但在其他子域中不可见。

如果我使用“.localexample.com”域,则cookie会正确存储到fr.localexample.com,而 在其他子域中可见。

如果我使用的是“localexample.com”域名,或者当我尝试使用“localexample”或“localhost”域名时,则无法存储该Cookie。

如果我使用“fr.localexample.com”或“.fr.localexample.com”域,则cookie会正确存储到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>

答案 2 :(得分:25)

localhost:您可以使用:domain: ".app.localhost"它可以使用。域名中的'domain'参数需要1个或多个点来设置Cookie。然后,您可以在localhost子域中运行会话,例如:api.app.localhost:3000

答案 3 :(得分:10)

使用显式域&#39; localhost&#39;设置Cookie时如下......

  

Set-Cookie:name = value;   的域=本地主机;到期=周四,2009年7月16日21:25:05 GMT;路径= /

...然后浏览器忽略它,因为它does not include at least two periods and is not one of seven specially handled, top level domains

  

...域必须至少有两(2)或三(3)个句点   防止形式的域名:&#34; .com&#34;,&#34; .edu&#34;和&#34; va.us&#34;。任何域名   在列出的七个特殊顶级域名之一内失败   以下只需要两个时期。任何其他域名至少需要   三。七个特殊的顶级域名是:&#34; COM&#34;,&#34; EDU&#34;,&#34; NET&#34;,   &#34; ORG&#34;,&#34; GOV&#34;,&#34; MIL&#34;和&#34; INT&#34;。

请注意,上述期间数可能假设需要一个领先期。然而,这段时间是ignored in modern browsers,它可能应该是......

  

至少一(1)或两(2)个期间

请注意,域属性的默认值为the host name of the server which generated the cookie response

所以没有为localhost设置cookie的解决方法是简单地不指定域属性并让浏览器使用默认值 - 这似乎没有与显式值相同的约束在domain属性中。

答案 4 :(得分:3)

结果我的浏览器有所不同。

Chrome- 127.0.0.1有效,但localhost .localhost和“”没有。 Firefox- .localhost工作但localhost,127.0.0.1和“”没有。

尚未在Opera,IE或Safari中测试

答案 5 :(得分:2)

花了很多时间自己解决这个问题。

使用PHP,此页面上的Nothing对我有用。我最终在我的代码中意识到PHP's session_set_cookie_params()的'secure'参数始终设置为TRUE。

由于我没有使用https访问localhost,我的浏览器永远不会接受cookie。所以,我修改了我的代码部分,以有条件地设置基于$ _SERVER ['HTTP_HOST']为'localhost'的'secure'参数。现在运作良好。

我希望这有助于某人。

答案 6 :(得分:1)

我使用127.0.0.1作为域测试本地运气好得多。我不知道为什么,但我的localhost和.localhost等结果好坏参与。

答案 7 :(得分:1)

没有任何建议的修复程序对我有用 - 将其设置为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=/;';
    }

答案 8 :(得分:1)

我遇到了同样的问题,我通过在cookie名称中加入2个点而不指定任何域来修复它。

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

答案 9 :(得分:1)

使用https://<local-domain>然后http://<local-domain>时似乎存在问题。在http://网站设置后,https://网站不会向请求发送Cookie。强制重新加载和清除缓存没有帮助。只能手动清除cookie。另外,如果我在https://页面上清除它们,那么http://页面将重新开始工作。

看起来与“严格安全的Cookie”有关。好的解释here。在2017-04-19上是released in Chrome 58

事实上,Chrome确实记录了安全Cookie和非安全Cookie,因为在点击地址栏图标时,它会根据页面的协议显示正确的Cookie。

但是,当同一域名存在同名的安全cookie时,Developer tools > Application > Cookies将不会显示非安全cookie,也不会向任何请求发送非安全cookie。这似乎是一个Chrome错误,或者如果出现这种情况,应该有一些方法可以在http页面上查看安全Cookie并指示它们被覆盖。

解决方法是使用不同的命名Cookie,具体取决于它们是用于http网站还是https网站,并将其命名为特定于您的应用。 __Secure-前缀表示cookie应该是严格安全的,并且也是一种很好的做法,因为安全和非安全不会发生冲突。 <{3}}也有前缀。

使用不同的/etc/hosts域进行https与http访问也会有效,但是一次意外https://localhost访问会阻止任何相同名称的Cookie在http://localhost网站上运行 - 所以这不是一个好的解决方法。

我已经提交了other benefits

答案 10 :(得分:1)

您可以使用localhost.org或更确切地说.localhost.org,它将始终解析为127.0.0.1

答案 11 :(得分:0)

Cookie需要指定SameSite属性,None曾经是默认值,但最近的浏览器版本将Lax设为默认值,以对某些类别的交叉网站请求伪造(CSRF)攻击。

SameSite=Lax一起,您还应该拥有Domain=localhost,因此您的cookie将与localhost关联并保存。它应该看起来像这样:

document.cookie = `${name}=${value}${expires}; Path=/; Domain=localhost; SameSite=Lax`;

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

答案 12 :(得分:0)

尝试了以上所有选项。对我有用的是:

  1. 确保对服务器的请求已将withCredentials设置为true。来自其他域的XMLHttpRequest不能为自己的域设置cookie值,除非在发出请求之前将withCredentials设置为true。
  2. 请勿设置Domain
  3. 设置Path=/

产生的Set-Cookie标头:

Set-Cookie: session_token=74528588-7c48-4546-a3ae-4326e22449e5; Expires=Sun, 16 Aug 2020 04:40:42 GMT; Path=/

答案 13 :(得分:0)

对我唯一有用的方法是在Cookie上设置Path=/

此外,路径属性的默认值似乎因浏览器而异,尽管我仅测试了其中两个(Firefox和Chrome)。

Chrome尝试按原样设置Cookie;如果path标头中省略了Set-Cookie属性,那么它将不会被存储和忽略。

但是,即使没有显式的path属性,Firefox也会存储cookie。它只是用请求的路径设置它;我的请求网址为/api/v1/users,并且路径已自动设置为/api/v1

无论如何,即使没有显式域(例如path或其他内容),当/设置为Domain=localhost时,两种浏览器都可以工作。因此,每种浏览器处理Cookie的方式有所不同。

答案 14 :(得分:0)

经过大量的实验并阅读了各种文章,这项工作奏效了。我可以设置多个Cookie,将它们重新读回,并将时间设置为负数并删除它们。

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

答案 15 :(得分:0)

如果要从另一个域设置cookie(即,通过发出XHR跨源请求来设置cookie),则需要确保在使用的XMLHttpRequest上将withCredentials属性设置为true按照here

的说明获取Cookie

答案 16 :(得分:0)

我正在玩一下。

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/
截至今天,

适用于Firefox和Chrome。但是,我没有找到一种方法让它与卷曲一起使用。我试过Host-Header和--resolve,没有运气,任何帮助都很感激。

但是,如果我将它设置为

,它可以卷曲
Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/

代替。 (这不适用于Firefox。)

答案 17 :(得分:0)

这里的答案都不适用于我。我通过将PHP作为页面中的第一件事来修复它。

与其他标头一样,必须在脚本的任何输出之前发送cookie(这是协议限制)。这要求您在任何输出之前调用此函数,包括和标记以及任何空格。

来自http://php.net/manual/en/function.setcookie.php

答案 18 :(得分:0)

document.cookie = valuename +&#34; =&#34; +值+&#34 ;; &#34; +到期+&#34 ;; domain =; path = /&#34 ;;

这&#34; domain =; path = /&#34 ;;将采用动态域,因为它的cookie将在子域中工作。 如果你想在localhost中测试它会工作

答案 19 :(得分:0)

另一个重要细节, expires = 应使用以下日期时间格式: Wdy,DD-Mon-YYYY HH:MM:SS GMT ({{3} })。

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