C# 具有和不具有指定域的Cookie(浏览器不一致)

C# 具有和不具有指定域的Cookie(浏览器不一致),c#,cookies,cross-browser,C#,Cookies,Cross Browser,我注意到浏览器之间在cookie方面存在一些真正的不一致 这将是相当长的时间,所以请容忍我 注意:我在我的主机文件中设置了一个名为“testdomain.com”的域,当使用“localhost”时,这个bug不会工作 注2:我很想知道这在Apache/PHP上是如何工作的,如果您按名称检索一个cookie,如果它返回一个cookie集合 维基百科 维基百科声明: 域和路径 cookie域和路径定义了 cookie他们告诉浏览器cookie只应发送回 给定域和路径的服务器如果未指定,则为 默认为

我注意到浏览器之间在cookie方面存在一些真正的不一致

这将是相当长的时间,所以请容忍我

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

注2:我很想知道这在Apache/PHP上是如何工作的,如果您按名称检索一个cookie,如果它返回一个cookie集合

维基百科 维基百科声明:

域和路径
cookie域和路径定义了 cookie他们告诉浏览器cookie只应发送回 给定域和路径的服务器如果未指定,则为 默认为所请求对象的域和路径。

因此,如果我们向下推:

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

});
Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});
我们应该获得一个cookie,其中使用的域是来自请求对象的域,在本例中,它应该是“testdomain.com”

W3 W3在Cookie规范中规定:

域=域

可选。“域”属性指定要为其指定域的域 cookie是有效的必须始终启动显式指定的域 带点。

因此,如果我们向下推:

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

});
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饼干

歌剧:1块饼干

Firefox:1 cookie

铬:1块饼干

如您所见,Opera和IE都设置了一个没有点前缀的显式域

Firefox和Chrome都使用点前缀设置显式域

如果我使用以下代码:

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

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

有趣的是,Firefox和Chrome都创建了没有点前缀的cookie

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

火狐:

铬:

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

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

});
就个人而言,我希望浏览器中存在一个cookie,因为我假设它基于cookie名称

以下是我观察到的:

在IE/Opera中,最后一个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>
看起来表单身份验证完全有可能推送过期的身份验证cookie,这与用户使用的身份验证cookie完全无关。它不使用当前身份验证Cookie的域

它无论如何都不能使用,因为域没有用cookie推回服务器

更新2 看来形式认证真的被打破了。如果在对用户进行身份验证时在cookie上使用显式域名,请等待会话超时,然后刷新页面,FormsAuthentication使用的生成cookie的方法将导致域为空,从而导致浏览器分配无点域

它要求预先为表单分配一个域,以便将表单分配给cookie,这破坏了多租户系统…

无法解释为什么对待cookie会有所不同,但一个快速解决方法是为每个子应用程序使用不同的cookie名称,而不是使用cookie的域


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

@WilliamBZA的建议帮助解决了最初的问题,但是导致cookie创建隐式域cookie的注销/会话超时错误让我得出结论,解决方案是

不要在.NET中使用显式Cookie。。。曾经

有太多的问题,当然可以通过在表单/域、Cookie/域等上显式来解决,以确保在任何地方都使用正确的域。但是,如果您的应用程序承载多个域或是多租户,那么问题就太大了


吸取教训。不要使用明确的cookies。

这可能应该分为自我回答的问题,详细描述可能出现的问题,以及回答中的解决方法。“很好的研究。还没有答案,”佩特阿卜杜林说。在我看来,在IE/Opera中使用显式域使旧cookie过期应该没问题(我也有类似的问题,但cookie只持续了几天),这真是令人震惊。我浪费了整整一个上午试图弄明白为什么Firefox在cookie域中添加了前缀点。太令人沮丧了!您可以通过设置
Cookie.Domain=”“
来防止前缀点,但Firefox仍会将其发送到其他子域。有趣的研究。我不知道.NET,但在我这方面,我总是在所有cookie中指定路径和域参数。域总是以点开始。这样的话,它就足够一致了,我从来没有遇到过你所描述的问题。