带有和不带有指定域的Cookie(浏览器不一致) [英] Cookies with and without the Domain Specified (browser inconsistency)

查看:2042
本文介绍了带有和不带有指定域的Cookie(浏览器不一致)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到浏览器之间在Cookie方面存在一些不一致的地方。



这将是非常漫长的。 >

注意:我在我的主机文件中设置了一个名为testdomain.com的域,此错误使用localhost。



注意2:我很想知道如何在Apache / PHP上工作它给出了一个cookie的集合。



维基百科



维基百科声明: http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path


域和路径

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


因此,如果我们按下:

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

});

我们应该从请求的对象获取一个使用域作为域的cookie,在这种情况下应为testdomain.com。



W3



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


Domain = domain



可选。 Domain属性指定
cookie有效的域。 明确指定的网域必须始终以点号开始


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



我们明确地推下主机名,我们应该在cookie上设置一个域名,



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


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






$ b



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

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

这是结果:



IE9 :1个Cookie





Opera:1个Cookie





Firefox:1个Cookie





Chrome:1个Cookie





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



如果我使用以下代码:


$ p <$ p <$ p <$ p <$ p <$ p <$ p < b $ b

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

});



IE / Opera:两者都有完全相同的结果, >

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



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



Firefox:





Chrome:





INTERSING BIT



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

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

});

PERSONALLY我希望在浏览器中存在一个cookie,因为我假设它基于cookie名称



这是我观察到的:



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



如果您明确定义带有点的域名,则两个浏览器仍会显示1个Cookie,即同名的最后一个Cookie。



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



我写了以下JavaScript来将值转储到页面: / p>

 < script type =text / javascript> 

(function(){
var cookies = document.cookie.split(';');
var output =;

(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 - 2个Cookie集(浏览器查看1):





Opera - 2个Cookie集(浏览器查看1):





Firefox - 2个Cookie集和浏览器看到2!:





Chrome - 2个Cookie设置和浏览器查看2!:










好:


  1. 当你访问cookie的名称在C#,它给你1个cookie。 (具有该名称的第一个Cookie)

  2. 浏览器向服务器发送所有Cookie

  3. 浏览器不会发送任何信息key的值。 (这意味着服务器不关心域)

  4. 如果您通过索引检索它们,则可以访问同一名称的两个cookie



    1. 问题...



      我们不得不改变我们的认证来指定cookie中的域名



      这打破了Chrome和Firefox,用户无法登录,因为服务器将尝试验证旧的验证cookie。这是因为(从我的理解)它使用认证Cookie名称来检索cookie。



      即使有两个cookie,第一个被检索,恰好是旧的,身份验证失败,用户没有登录。SOMETIMES正确的cookie是首先在列表中,身份验证成功...



      最初,我们通过推送旧域的Cookie来解决这个问题。这在Chrome和Firefox中有效。



      但它现在打破了IE / Opera,因为两个浏览器都不关心域名,只比较基于名称的cookie。 / p>

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



      假设我们必须指定域,我们不能依赖用户清除其浏览器缓存。我们如何解决这个问题?



      更新:



      了解.NET如何标记用户。

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

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



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



      更新2



      这似乎FormsAuthentication真的坏了。如果在对用户进行身份验证时在Cookie上使用显式域名,请等待会话超时,然后刷新页面,生成由FormsAuthentication使用的Cookie的方法会导致域为空,导致浏览器分配



      它要求为表单分配一个域,以便将其分配给该cookie,这将打破多租户系统...

      解决方案

      @ WilliamBZA的建议帮助解决了初始问题,但后来出现/会话超时错误导致cookie创建一个隐式域cookie我得出的结论是解决方案是...



      不要在.NET中使用显式Cookie ...



      有太多的问题,确定他们可以通过在表单/域,Cookie /域等上显式来解决。正确的域被使用无处不在。但是,如果您的应用程序托管多个域或者是多租户,那么它就变得太有问题了。



      学习教训。不要使用显式Cookie。


      I've noticed that there are some real inconsistencies between browsers in terms of cookies.

      This is going to be rather long so bare with me.

      Note: I've setup a domain in my host file called "testdomain.com", this bug WONT work when using "localhost".

      Note2: I am curious to know how this works on Apache/PHP if when you retrieve a cookie by name if it gives a collection of cookies back.

      Wikipedia

      Wikipedia states that: http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path

      Domain and Path
      The cookie domain and path define the scope of the cookie—they tell the browser that cookies should only be sent back to the server for the given domain and path. If not specified, they default to the domain and path of the object that was requested.

      So if we push down:

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

      We should get a cookie with the domain used being the domain from the requested object, in this case it should be "testdomain.com".

      W3

      W3 states in the specification for cookies: http://www.w3.org/Protocols/rfc2109/rfc2109

      Domain=domain

      Optional. The Domain attribute specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot.

      So if we push down:

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

      We pushed down the host-name explicitly, we should get a domain name set on the cookie which would be prefixed with the dot, in this case it should be ".testdomain.com".

      It also states what's on Wikipedia:

      Domain Defaults to the request-host. (Note that there is no dot at the beginning of request-host.)


      With me so far?

      If I use the first method, defining a Domain:

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

      This is the results:

      IE9: 1 cookie

      Opera: 1 cookie

      Firefox: 1 cookie

      Chrome: 1 cookie

      As you can see, both Opera and IE both set an EXPLICIT domain without the dot prefix.

      Both Firefox and Chrome DO set the EXPLICIT domain with a dot prefix.

      If I use the following code:

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

      IE / Opera: Both have the exact same result, the domain WITHOUT the dot prefix.

      Funnily enough, Firefox and Chrome both create cookies WITHOUT the dot prefix.

      (I cleared all cookies and ran the code again)

      Firefox:

      Chrome:

      INTERESTING BIT

      This is where it gets interesting. If I write the cookies one after another like so:

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

      PERSONALLY I would expect one cookie to exist in the browser, because I assume it's based on the cookie name.

      Here's what i've observed:

      In IE / Opera, the LAST cookie set is the cookie that is used. This is because the Cookie name and Domain name are identical.

      If you explicitly define a domain name with a dot, both browser will still see 1 cookie, the last cookie of the same name.

      Chrome and Firefox on the other hand, see more than 1 cookie:

      I wrote the following JavaScript to dump the values to the page:

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

      These are the results:

      IE - 2 cookies set (browser sees 1):

      Opera - 2 cookies set (browser sees 1):

      Firefox - 2 cookies set and browser sees 2!:

      Chrome - 2 cookies set and browser sees 2!:


      Now you're probably wondering wtf all this is.

      Well:

      1. When you access the cookie by Name in C#, it gives you 1 cookie. (the first cookie that has that name)
      2. The browser sends ALL cookies to the server
      3. The browser doesn't send any information other than the key/value of the cookie. (this means the server doesn't care about the domain)
      4. You can access both cookies of the same name, if you retrieve them by index

      The problem...

      We had to change our Authentication to specify the domain in the cookie when we pushed it down.

      This broke Chrome and Firefox, users were no longer able to login, because the server would try authenticate the old auth cookie. This is because (from my understanding) it uses the Authentication Cookie Name to retrieve the cookie.

      Even tho there are two cookies, the first one is retrieved which happens to be the old one, authentication fails, user isn't logged in. SOMETIMES the correct cookie is first in the list, and the authentication succeeds...

      Initially we solved this by pushing a cookie with the old domain to expire it. This worked in Chrome and Firefox.

      But it now broke IE/Opera since both browsers don't care about the domain and only compare the cookie based on the name.

      My conclusion is that the domain on a cookie is a complete utter waste of time.

      Assuming that we must specify the domain, and we can't rely on users to clear their browser cache. How can we resolve this problem?

      Update:

      Digging into how .NET signs a user out.

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

      It looks like it's entirely possible for the Forms authentication to push an expired Auth cookie, that is entirely unrelated to the cookie the user is authenticated with. It doesn't use the current Auth Cookie's domain.

      Which it can't use anyway, since the domain isn't pushed back to the server with the cookie.

      Update 2

      It seems FormsAuthentication is really broken. If you use an explicit domain name on a cookie when you authenticate the user, wait for the session to timeout, then refresh the page, the method of generating the cookie used by FormsAuthentication results in the domain being null which causes the browser to assign a dotless domain.

      It requires that Forms be assigned a domain up front for it to be assigned to the cookie, this breaks a multi-tenant system...

      解决方案

      @WilliamBZA's suggestion helped solve the initial problem, but then signout/session timeout bug that results in the cookie creating an implicit domain cookie has made me come to the conclusion that the solution is...

      Don't use Explicit cookies in .NET... ever

      There are far too many problems, sure they can be solved by being explicit on the Form/Domain, Cookie/Domain, etc. To ensure that the correct domain is used everywhere. But if your application hosts multiple domains or is multi tenant, then it just becomes too problematic.

      Lesson is learnt. Don't use explicit cookies.

      这篇关于带有和不带有指定域的Cookie(浏览器不一致)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆