我们不久前将我们的网站迁移到了一个新的托管服务商,并且经常出现人们无法注销的问题。不确定这是否与托管环境或代码更改有关。
这是相关位的Wireshark日志 - 所有这些都发生在同一个TCP流中。
来自浏览器的退出请求(请注意身份验证Cookie):
GET /cirrus/logout HTTP/1.1
Host: subdomain.domain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://subdomain.domain.com/cirrus/CA/Admin/AccountSwitch
Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye
X-LogDigger-CliVer: client-firefox 2.1.5
X-LogDigger: logme=0&reqid=fda96ee5-2db4-f543-81b5-64bdb022d358&
Connection: keep-alive
服务器响应。它清除cookie值并重定向
HTTP/1.1 302 Found
Server: nginx
Date: Fri, 22 Nov 2013 14:40:22 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 124
Connection: keep-alive
Cache-Control: private, no-cache="Set-Cookie"
Location: /cirrus
Set-Cookie: USER.AUTH=; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus
X-Powered-By: ASP.NET
X-UA-Compatible: chrome=IE8
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/cirrus">here</a>.</h2>
</body></html>
浏览器遵循重定向,但使用旧的cookie值:
GET /cirrus HTTP/1.1
Host: subdomain.domain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://subdomain.domain.com/cirrus/CA/Admin/AccountSwitch
Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye
X-LogDigger-CliVer: client-firefox 2.1.5
X-LogDigger: logme=0&reqid=0052e1e1-2306-d64d-a308-20f9fce4702e&
Connection: keep-alive
Set-Cookie标头中是否有任何明显的缺失可能会阻止浏览器删除cookie?
要更改现有Cookie的值,以下Cookie参数必须匹配:
名称和路径设置为explecitely,域不是。这可能是问题吗?
编辑:因为有人问过为什么过去设定过期日期,所以背景更多。 这是对AppHarbor Security插件的略微修改:https://github.com/appharbor/AppHarbor.Web.Security 修改是包括cookie的路径。请在此处找到修改后的注销方法:
public void SignOut(string path)
{
_context.Response.Cookies.Remove(_configuration.CookieName);
_context.Response.Cookies.Add(new HttpCookie(_configuration.CookieName, "")
{
Expires = DateTime.UtcNow.AddMonths(-100),
Path = path
});
}
过去的过期日期由AppHarbor插件完成,这是常见做法。见http://msdn.microsoft.com/en-us/library/ms178195(v=vs.100).aspx
答案 0 :(得分:1)
我猜测历史到期日会导致整个Set-Cookie行被忽略(为什么设置一个8年前过期的cookie?)。
expires=Fri, 22-Jul-2005
答案 1 :(得分:1)
我们在过去删除Cookie时遇到了问题,是的,域和路径必须与您尝试删除的Cookie的域和路径相匹配。
尝试在HttpCookie
。
答案 2 :(得分:1)
很棒的问题和优秀的笔记。我最近也遇到过这个问题。
除了您应该做的事情之外,还有一种自动防范方法:
Set-Cookie: USER.AUTH=invalid; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus; domain=subdomain.domain.com
故障安全方法如下:
最后为所有Cookie添加一个特殊字符串。除非该字符串存在,否则拒绝cookie并强制重置它。例如,所有新cookie必须如下所示:
Set-Cookie: USER.AUTH=AOvDEjH3w6xIxUC0sYNOAQR5BZ7pPmEF0RMxqohERN87Ti03Eqxd7rQC/BveqmaszmFg8QoSonP+Z+mtQQivKpvloFsQYretYKR8ENubj+moUBF479K5e4albKxS9mBEWT5Xy/XCnEyCPqLASGLY09ywkmIilNU1Ox4J3fCtYXHelE/hyzuKe9y3ui5AKEbbGs3sN9q1zYjVjHKKiNIGaHvjJ2zn7ZUs042B82Jc9RHzt0JW8dnnrl3mAkN1lJQogtlG+ynQSCyQD8YzgO8IpOnSXLJLaCMGMQcvSyX4YKJU/9sxgA5r5cZVCkHLsReS3eIJtXoxktMO6nxVZJY6MX1YwuJOgLRQvwBy9FFnQ6ye|1386510233; expires=Fri, 22-Jul-2005 14:40:17 GMT; path=/cirrus; domain=subdomain.domain.com
注意更改:存储在USER.AUTH
中的极长字符串以|1386510233
结尾,这是设置cookie时的unix时期。
这为cookie解析添加了一个简单的额外步骤。现在你需要测试|
的存在并丢弃unix时代,除非你想知道cookie何时被设置。为了使其更快,您可以检查string[length-10]==|
而不是解析整个字符串。在我这样做的过程中,我将字符串拆分为|
并在拆分后检查两个值。这绕过了一个由两部分组成的解析过程,但这个方面是特定于语言的,当涉及到你选择的策略时,它实际上只是优先考虑。如果您打算丢弃该值,只需检查您希望|
所在的特定索引。
将来如果再次更改主机,您可以测试该unix时期并拒绝早于特定时间点的cookie。这最多会为您的cookie处理程序添加两个额外的进程:删除|unixepoch
,如果需要,在再次更改主机时检查该时间是否拒绝cookie。这会为页面加载增加约0.001s
或更少。与客户服务失败和大规模脑损伤相比,这是值得的。
您的新Cookie策略允许您在没有|unixepoch
的情况下轻松拒绝所有Cookie,因为您知道它们是旧Cookie。是的,人们可能会抱怨这种方法,但这是真正了解cookie有效的唯一方法。您不能依赖客户端为您提供有效的cookie。除非你想存储大量数据,否则你无法记录每一个cookie。如果您每次都存储每个cookie并进行检查,那么在此策略中可以将0.01s
添加到页面加载而不是0.001s
,因此仓库路线不值得。
另一种方法是使用USER.AUTHENTICATION
而不是USER.AUTH
作为新的Cookie值,但这可能更具侵略性。如果/当你再次更换主机时,你没有从上面所说的内容中获益。
祝你过渡顺利。我希望你能解决这个问题。使用上面的策略,我能够。