Phi*_*ill 44 c# cookies cross-browser
我注意到,在cookie方面,浏览器之间存在一些真正的不一致.
这将是相当长的,所以请耐心等待.
注意:我在我的主机文件中设置了一个名为"testdomain.com"的域,这个错误 WONT 在使用"localhost"时起作用.
注意2:我很想知道如果它按照名称检索cookie,如果它提供了一系列cookie,那么它在Apache/PHP上是如何工作的.
维基百科声明:http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path
域和路径
cookie域和路径定义cookie的范围 - 它们告诉浏览器只应将cookie发送回给定域和路径的服务器.如果未指定,则它们默认为请求的对象的域和路径.
所以如果我们推倒:
Response.Cookies.Add(new HttpCookie("Banana", "2")
{
});
Run Code Online (Sandbox Code Playgroud)
我们应该获得一个cookie,其中所使用的域是来自请求对象的域,在这种情况下它应该是"testdomain.com".
W3在cookie规范中说明:http://www.w3.org/Protocols/rfc2109/rfc2109
域=域名
可选的.Domain属性指定cookie有效的域. 明确指定的域必须始终以点开头.
所以如果我们推倒:
Response.Cookies.Add(new HttpCookie("Banana", "1")
{
Domain = Request.Url.Host
});
Run Code Online (Sandbox Code Playgroud)
我们明确地推下了主机名,我们应该在cookie上设置一个以点为前缀的域名,在这种情况下它应该是".testdomain.com".
它还说明了维基百科上的内容:
域默认为请求主机.(请注意,request-host开头没有点.)
和我一起到目前为止?
如果我使用第一种方法,则定义域:
Response.Cookies.Add(new HttpCookie("Banana", "1")
{
Domain = Request.Url.Host
});
Run Code Online (Sandbox Code Playgroud)
这是结果:
IE9:1个cookie
Opera:1个cookie
Firefox:1个cookie
Chrome:1个Cookie
如您所见,Opera和IE都设置了一个没有点前缀的EXPLICIT域.
Firefox和Chrome DO都使用点前缀设置EXPLICIT域.
如果我使用以下代码:
Response.Cookies.Add(new HttpCookie("Banana", "2")
{
});
Run Code Online (Sandbox Code Playgroud)
IE/Opera:两者都有完全相同的结果,没有点前缀的域.
有趣的是,Firefox和Chrome都创建了没有点前缀的cookie.
(我清除了所有cookie并再次运行代码)
火狐:
铬:
这是它变得有趣的地方.如果我像这样一个接一个地写饼干:
Response.Cookies.Add(new HttpCookie("Banana", "1")
{
Domain = Request.Url.Host
});
Response.Cookies.Add(new HttpCookie("Banana", "2")
{
});
Run Code Online (Sandbox Code Playgroud)
个人我希望浏览器中存在一个cookie,因为我认为它基于cookie名称.
这是我观察到的:
在IE/Opera中,LAST cookie集是使用的cookie.这是因为Cookie名称和域名相同.
如果您明确定义带有点的域名,则两个浏览器仍会看到1个cookie,即同名的最后一个cookie.
另一方面,Chrome和Firefox会看到超过1个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>
Run Code Online (Sandbox Code Playgroud)
这些是结果:
IE - 2个cookie设置(浏览器看到1):
Opera - 2个cookie集(浏览器看到1):
Firefox - 2个cookie设置和浏览器看到2!:
Chrome - 2个Cookie设置和浏览器看到2!:
现在你可能想知道wtf这一切.
好:
问题...
我们必须更改我们的身份验证,以便在我们将其推送时在cookie中指定域.
这打破了Chrome和Firefox,用户无法再登录,因为服务器会尝试验证旧的auth cookie.这是因为(根据我的理解)它使用身份验证Cookie名称来检索cookie.
即使有两个cookie,第一个检索到的是旧的,验证失败,用户没有登录.有些正确的cookie首先在列表中,验证成功...
最初,我们通过推送旧域的cookie来解决这个问题.这适用于Chrome和Firefox.
但它现在破坏了IE/Opera,因为两个浏览器都不关心域名,只根据名称比较cookie.
我的结论是,cookie上的域名完全是浪费时间.
假设我们必须指定域,并且我们不能依赖用户来清除他们的浏览器缓存.我们如何解决这个问题?
深入研究.NET如何签署用户.
if (FormsAuthentication._CookieDomain != null)
{
httpCookie.Domain = FormsAuthentication._CookieDomain;
}
Run Code Online (Sandbox Code Playgroud)
看起来Forms身份验证完全有可能推送过期的Auth cookie,这与用户通过身份验证的cookie完全无关.它不使用当前的Auth Cookie域.
无论如何它都不能使用,因为域没有被推回到带有cookie的服务器.
似乎FormsAuthentication真的坏了.如果在对用户进行身份验证时在cookie上使用显式域名,请等待会话超时,然后刷新页面,生成FormsAuthentication使用的cookie的方法导致域为null,这会导致浏览器分配无网域.
它要求预先为表单分配一个域,以便将其分配给cookie,这会破坏多租户系统......
@WilliamBZA的建议帮助解决了最初的问题,但随后导致cookie创建隐式域cookie的注销/会话超时错误让我得出结论,解决方案是......
不要在.NET中使用Explicit cookies ...永远
有太多的问题,确定它们可以通过在表单/域,Cookie /域等上明确来解决.确保在任何地方使用正确的域.但是,如果您的应用程序托管多个域或多租户,那么它就会变得太麻烦了.
课程是学到的.不要使用显式cookie.
无法理解为什么对cookie的处理方式不同,但快速解决方法是为每个子应用程序使用不同的cookie名称,而不是使用cookie的域.
在Forms Authentication的情况下,更改ASPXAUTH cookie的名称.
归档时间: |
|
查看次数: |
37349 次 |
最近记录: |