有和没有指定域名的Cookie(浏览器不一致)

我注意到,在浏览器之间有一些cookie的真正的不一致之处。

这对我来说将是相当长的。

注意:我在我的主机文件“testdomain.com”中设置了一个域,这个bug在使用“localhost”的时候工作。

注2:我很好奇,知道如果这个工作在Apache / PHP上时,如果它返回一个cookie的集合,如果你通过名字检索一个cookie。

维基百科

维基百科指出: http : //en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path

域和path
Cookie域和path定义了Cookie的范围 – 它们告诉浏览器,cookies应该只发送给给定域和path的服务器。 如果未指定,则默认为请求的对象的域和path。

所以如果我们按下:

Response.Cookies.Add(new HttpCookie("Banana", "2") { }); 

我们应该从所请求的对象中获得一个域作为域的cookie,在这种情况下,它应该是“testdomain.com”。

W3

W3在cookies的规范中声明: http : //www.w3.org/Protocols/rfc2109/rfc2109

域=域名

可选的。 “域”属性指定cookie有效的域。 明确指定的域必须始终以点开头。

所以如果我们按下:

 Response.Cookies.Add(new HttpCookie("Banana", "1") { Domain = Request.Url.Host }); 

我们明确地推下了主机名,我们应该在cookie上设置一个域名,这个域名会以“.testdomain.com”作为前缀。

它还说明了维基百科上的内容:

域默认为请求主机。 (请注意,请求主机的开头没有点。)


跟我到目前为止?

如果我使用第一种方法,定义一个域:

 Response.Cookies.Add(new HttpCookie("Banana", "1") { Domain = Request.Url.Host }); 

这是结果:

IE9:1 cookie

IE与1个cookie和域明确设置

歌剧:1个cookies

歌剧与1个cookie和域明确设置

Firefox:1个cookie

带有1个cookie和明确设置的域的Firefox

Chrome:1个Cookie

具有1个Cookie和明确设置的域的Chrome

正如你所看到的,Opera和IE都设置了一个不带点前缀的EXPLICIT域。

Firefox和Chrome DO都使用点前缀来设置EXPLICIT域。

如果我使用下面的代码:

 Response.Cookies.Add(new HttpCookie("Banana", "2") { }); 

IE / Opera:两者具有完全相同的结果,域没有点前缀。

有趣的是,Firefox和Chrome都创build没有点前缀的cookie。

(我清除了所有的cookies并再次运行代码)

火狐:

带有1个cookie和明确设置的域的Firefox

铬:

具有1个Cookie和明确设置的域的Chrome

有趣的位

这是它变得有趣的地方。 如果我像这样一个接一个地写cookies:

 Response.Cookies.Add(new HttpCookie("Banana", "1") { Domain = Request.Url.Host }); Response.Cookies.Add(new HttpCookie("Banana", "2") { }); 

我个人希望在浏览器中存在一个cookie,因为我认为它是基于cookie的名字。

以下是我所观察到的:

在IE / Opera中,LAST cookie集是使用的cookie。 这是因为Cookie名称和域名是相同的。

如果您明确定义了一个带有点的域名,那么这两个浏览器仍然会看到1个cookie,即最后一个同名的cookie。

Chrome和Firefox另一方面,看到多个cookie:

我写了下面的JavaScript将这些值转储到页面上:

 <script type="text/javascript"> (function () { var cookies = document.cookie.split(';'); var output = ""; for (var i = 0; i < cookies.length; i++) { output += "<li>Name " + cookies[i].split('=')[0]; output += " - Value " + cookies[i].split('=')[1] + "</li>"; } document.write("<ul>" + output + "</ul>"); })(); </script> 

这是结果:

IE – 2cookies设置(浏览器见1):

IE  -  2饼干设置,结果

歌剧-2cookies套装(浏览器见1):

在这里输入图像说明

Firefox – 2个Cookie设置和浏览器见2 !:

在这里输入图像说明

Chrome – 2cookies套装和浏览器见2 !:

在这里输入图像说明


现在你可能想知道所有这一切。

好:

  1. 当您通过C#中的名称访问cookie时,会为您提供1个Cookie。 (具有该名称的第一个cookie)
  2. 浏览器将所有cookie发送到服务器
  3. 浏览器不会发送cookie以外的任何信息。 (这意味着服务器不关心域)
  4. 如果您通过索引检索它们,您可以访问同名的两个cookie

问题…

我们必须改变我们的身份validation,以便在我们推送时指定cookie中的域名。

这打破了Chrome和Firefox,用户不再能够login,因为服务器会尝试validation旧的身份validationcookie。 这是因为(从我的理解),它使用authenticationCookie名称来检索cookie。

即使是有两个cookies,第一个被检索,这恰好是旧的,身份validation失败,用户没有login。有时正确的cookie是第一个在列表中,身份validation成功…

最初我们通过推送一个旧域的cookie来解决这个问题。 这在Chrome和Firefox中起作用。

但是现在它破坏了IE / Opera,因为两个浏览器都不关心这个域名,而只是根据这个名字比较这个cookie。

我的结论是,cookie上的域名完全是浪费时间。

假设我们必须指定域,并且我们不能依靠用户来清除他们的浏览器caching。 我们如何解决这个问题?

更新:

挖掘.NET如何签署用户。

 if (FormsAuthentication._CookieDomain != null) { httpCookie.Domain = FormsAuthentication._CookieDomain; } 

看起来,Forms身份validation完全可能推送过期的Auth cookie,这与用户通过身份validation的cookie完全无关。 它不使用当前的Auth Cookie域。

无论如何它不能使用它,因为域不会被cookie推回到服务器。

更新2

看来FormsAuthentication真的被打破了。 如果在对用户进行身份validation时使用cookie上的显式域名,请等待会话超时,然后刷新页面,生成由FormsAuthentication使用的cookie的方法结果为null,这会导致浏览器分配一个无点域名

它要求表单被分配一个域,它被分配到cookie,这打破了多租户系统…

@ WilliamBZA的build议帮助解决了最初的问题,但后来注销/会话超时错误,导致在创build一个隐含的域cookie的cookie使我得出结论,解决scheme是…

不要在.NET中使用明确的cookies …永远

有太多的问题,肯定可以通过明确的表单/域名,Cookie /域名等来解决。确保正确的域名无处不在。 但是,如果您的应用程序托pipe多个域或多租户,那么它就成了问题。

经验教训。 不要使用明确的cookies。

无法帮助为什么 cookie被区别对待,但是一个快速的解决办法是每个子应用程序使用不同的cookie名称,而不是使用cookie的域名。

在表单身份validation的情况下,更改ASPXAUTH cookie的名称。