清除缓存后 set-cookie 不适用于 IE11/10
set-cookie not working for IE11/10 after clearing cache
我目前遇到一个问题,即在清除 cache/cookies IE10 和 IE11 后将不再设置 cookie。请求和响应看起来几乎相同,但在清除缓存后,cookie 永远不会被传递,即使它似乎设置正确。
下面是我的登录方法流程:
1. VerifyLogin() -> Fail: Go To Login page
-> Pass: Call rest of the AJAX Methods // Enter Login Credentials and submit
2. Authentication() -> Fail: Prompt the user
-> Pass: set forms auth cookie and navigate back to original page, where it will call VerifyLogin() again
一旦 Authentication() 通过,他们就应该顺利通过 VerifyLogin() 并继续使用该产品。现在,所有调用都将传递表单身份验证 cookie。
在我看到它失败的实例中,Authentication() 调用通过并获得 200 OK(并有一个 set-cookie 响应 header)但是,VerifyLogin() 然后失败,因为它还没有放弃饼干。
我很难重现这个,但到目前为止我的重现步骤如下。这是从没有 IE 运行 的实例开始的。我不是 100% 确定这与我的客户遇到的问题完全相同,但它似乎揭示了他们所看到的相同问题。
- 启动 IE
- 浏览到站点的索引页面并跳转到登录页面(验证失败)
- 使用凭据登录,Authentication() returns 200 OK 并有 set-cookie 响应 header。然后它会导航您并调用通过的 VerifyLogin() 。 cookie 在请求中发送,并且全部成功。随后调用所有工作。
- 清除我的缓存和 cookies
- 浏览到站点的索引页面并跳转到登录页面(验证失败,这是应该的)
- 使用凭据登录,Authentication() returns 200 OK 并有 set-cookie 响应 header。然后它会引导您并在此时调用 VerifyLogin() 失败。 cookie 不会在请求中传递,即使它先前已在 Authentication() 的响应中设置。如果我关闭并重新打开 IE,它将再次工作。
所以,就像第二次 set-cookie 响应只是没有设置 cookie。
首先,这是我的 web.config 的相关部分以及我如何设置表单 cookie。
web.config:
<authentication mode="Forms">
<forms enableCrossAppRedirects="true" name="Gator.Express.Auth" timeout="2880" />
</authentication>
setAuthenticationCookie 方法:
public void SetAuthenticationCookie(string userName, CookieData cookieData)
{
//In order to pickup the settings from config, we create a default cookie and use its values to create a
//new one.
var cookie = FormsAuthentication.GetAuthCookie(userName, true);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket == null)
throw new Exception("Error setting authorisation cookie. Decryption of default cookie failed.");
var jsonToken = JsonConvert.SerializeObject(cookieData);
var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration,
ticket.IsPersistent, jsonToken, ticket.CookiePath);
var encTicket = FormsAuthentication.Encrypt(newTicket);
cookie.Value = encTicket;
HttpContext.Current.Response.Cookies.Add(cookie);
}
下面是请求和响应的顺序。
工作验证请求
POST http://localhost:55733/api/Authentication HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:61496/Login.html
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Content-Length: 35
DNT: 1
Host: localhost:55733
Pragma: no-cache
Username=michaelGator&Password=XXXX
# 工作验证响应
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
Set-Cookie: Gator.Express.Auth=01020FCCF4658183D208FE0F4CC8BA1385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
Set-Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:28:39 GMT; path=/; HttpOnly
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:28:39 GMT
Content-Length: 14
"michaelGator"
# 工作验证登录请求
GET http://localhost:55733/api/VerifyLogin HTTP/1.1
Referer: http://localhost:61496/
Accept: */*
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
DNT: 1
Host: localhost:55733
Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF
# 工作 VerifyLogin 响应
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:28:39 GMT
Content-Length: 0
下面是 non-working 组请求和响应。请注意,身份验证方法 returns 一个 200 OK 和一个 set-cookie 命令,但在下一个验证登录调用中,cookie 消失了。
# 身份验证请求 - Returns 它应该是 non-working 请求集的一部分
POST http://localhost:55733/api/Authentication HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:61496/Login.html
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Content-Length: 35
DNT: 1
Host: localhost:55733
Pragma: no-cache
Username=michaelGator&Password=XXXX
# 身份验证响应- Returns 它应该是 non-working 请求集的一部分
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
Set-Cookie: Gator.Express.Auth=01022054EB9B8183D208FE20D4BEF01385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
Set-Cookie: Gator.Express.Auth=01028447109C8183D208FE84C7E3F01385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:30:10 GMT; path=/; HttpOnly
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:30:10 GMT
Content-Length: 14
"michaelGator"
# Non-Working 验证登录请求 - 注意,没有 cookie 传递
GET http://localhost:55733/api/VerifyLogin HTTP/1.1
Referer: http://localhost:61496/
Accept: */*
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
DNT: 1
Host: localhost:55733
# Non-Working VerifyLogin 响应 - 失败,因为没有传递任何 Forms Cookie
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:30:10 GMT
Content-Length: 71
{"$id":"1","Message":"Authorization has been denied for this request."}
有人对此有什么想法吗?
为什么响应发送两个 SetCookie
headers 具有相同的 cookie 名称?这似乎……错误且令人困惑。
注意不要给 IE 过多的 cookie 数据。您的 cookie 值很长! cookie 限制为 ~4k。这是您域的 cookie 总数。如果超过这个长度,IE 将不会返回。
HTH
您似乎获得了两个身份验证 cookie,这表明您的实施与 ASP.Net 试图为您自动执行的内容发生冲突。
有一个 FormsAuthentication.SetAuthCookie
创建和设置 cookie,我认为这已经应用了,所以:
FormsAuthentication.SetAuthCookie
获取 cookie(已在同一响应中设置)。
- 你的
SetAuthenticationCookie
开火了。
- 这会调用
FormsAuthentication.GetAuthCookie
并处理(将 JSON 序列化数据嵌入到新的 cookie 中)原始数据。
- 您调用
HttpContext.Current.Response.Cookies.Add
创建第二个 cookie。
- 两个 cookie 在 header 中以相同的名称
传送
你没有清除原始cookie,.Net不知道如何处理你处理过的cookie。
我想你有两个选择:
- 将您的 JSON 数据拆分到一个完全独立的 cookie 中,并使用不同的名称。
- 从头开始制作您自己的 cookie,不要使用 .Net 的任何
FormsAuthentication
方法。
我个人认为前者是最简单、实施起来最快的。
尝试 cookie 名称可能也值得 - 我不确定所有浏览器都支持 cookie 名称中的句点,但它们都区分大小写。
最后还有一些值得检查的东西 - 它几乎是 never worth setting a cookie's path in .Net,因为 IIS 将 URL 视为不区分大小写,但浏览器都将 cookie 名称视为 case-sensitive。
我目前遇到一个问题,即在清除 cache/cookies IE10 和 IE11 后将不再设置 cookie。请求和响应看起来几乎相同,但在清除缓存后,cookie 永远不会被传递,即使它似乎设置正确。
下面是我的登录方法流程:
1. VerifyLogin() -> Fail: Go To Login page
-> Pass: Call rest of the AJAX Methods // Enter Login Credentials and submit
2. Authentication() -> Fail: Prompt the user
-> Pass: set forms auth cookie and navigate back to original page, where it will call VerifyLogin() again
一旦 Authentication() 通过,他们就应该顺利通过 VerifyLogin() 并继续使用该产品。现在,所有调用都将传递表单身份验证 cookie。
在我看到它失败的实例中,Authentication() 调用通过并获得 200 OK(并有一个 set-cookie 响应 header)但是,VerifyLogin() 然后失败,因为它还没有放弃饼干。
我很难重现这个,但到目前为止我的重现步骤如下。这是从没有 IE 运行 的实例开始的。我不是 100% 确定这与我的客户遇到的问题完全相同,但它似乎揭示了他们所看到的相同问题。
- 启动 IE
- 浏览到站点的索引页面并跳转到登录页面(验证失败)
- 使用凭据登录,Authentication() returns 200 OK 并有 set-cookie 响应 header。然后它会导航您并调用通过的 VerifyLogin() 。 cookie 在请求中发送,并且全部成功。随后调用所有工作。
- 清除我的缓存和 cookies
- 浏览到站点的索引页面并跳转到登录页面(验证失败,这是应该的)
- 使用凭据登录,Authentication() returns 200 OK 并有 set-cookie 响应 header。然后它会引导您并在此时调用 VerifyLogin() 失败。 cookie 不会在请求中传递,即使它先前已在 Authentication() 的响应中设置。如果我关闭并重新打开 IE,它将再次工作。
所以,就像第二次 set-cookie 响应只是没有设置 cookie。
首先,这是我的 web.config 的相关部分以及我如何设置表单 cookie。
web.config:
<authentication mode="Forms">
<forms enableCrossAppRedirects="true" name="Gator.Express.Auth" timeout="2880" />
</authentication>
setAuthenticationCookie 方法:
public void SetAuthenticationCookie(string userName, CookieData cookieData)
{
//In order to pickup the settings from config, we create a default cookie and use its values to create a
//new one.
var cookie = FormsAuthentication.GetAuthCookie(userName, true);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket == null)
throw new Exception("Error setting authorisation cookie. Decryption of default cookie failed.");
var jsonToken = JsonConvert.SerializeObject(cookieData);
var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration,
ticket.IsPersistent, jsonToken, ticket.CookiePath);
var encTicket = FormsAuthentication.Encrypt(newTicket);
cookie.Value = encTicket;
HttpContext.Current.Response.Cookies.Add(cookie);
}
下面是请求和响应的顺序。
工作验证请求
POST http://localhost:55733/api/Authentication HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:61496/Login.html
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Content-Length: 35
DNT: 1
Host: localhost:55733
Pragma: no-cache
Username=michaelGator&Password=XXXX
# 工作验证响应
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
Set-Cookie: Gator.Express.Auth=01020FCCF4658183D208FE0F4CC8BA1385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
Set-Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:28:39 GMT; path=/; HttpOnly
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:28:39 GMT
Content-Length: 14
"michaelGator"
# 工作验证登录请求
GET http://localhost:55733/api/VerifyLogin HTTP/1.1
Referer: http://localhost:61496/
Accept: */*
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
DNT: 1
Host: localhost:55733
Cookie: Gator.Express.Auth=0102054E17668183D208FE05CEEABA1385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF
# 工作 VerifyLogin 响应
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:28:39 GMT
Content-Length: 0
下面是 non-working 组请求和响应。请注意,身份验证方法 returns 一个 200 OK 和一个 set-cookie 命令,但在下一个验证登录调用中,cookie 消失了。
# 身份验证请求 - Returns 它应该是 non-working 请求集的一部分
POST http://localhost:55733/api/Authentication HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:61496/Login.html
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Content-Length: 35
DNT: 1
Host: localhost:55733
Pragma: no-cache
Username=michaelGator&Password=XXXX
# 身份验证响应- Returns 它应该是 non-working 请求集的一部分
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
Set-Cookie: Gator.Express.Auth=01022054EB9B8183D208FE20D4BEF01385D208000C6D00690063006800610065006C004700610074006F00720000012F00FF; path=/; HttpOnly
Set-Cookie: Gator.Express.Auth=01028447109C8183D208FE84C7E3F01385D208010C6D00690063006800610065006C004700610074006F007200377B002200530073006F004100630063006F0075006E0074004900640022003A002200300030003000300030003000300030002D0030003000300030002D0030003000300030002D0030003000300030002D0030003000300030003000300030003000300030003000300022007D00012F00FF; expires=Sun, 05-Jul-2015 08:30:10 GMT; path=/; HttpOnly
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcQXV0aGVudGljYXRpb24=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:30:10 GMT
Content-Length: 14
"michaelGator"
# Non-Working 验证登录请求 - 注意,没有 cookie 传递
GET http://localhost:55733/api/VerifyLogin HTTP/1.1
Referer: http://localhost:61496/
Accept: */*
Accept-Language: en-GB
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
DNT: 1
Host: localhost:55733
# Non-Working VerifyLogin 响应 - 失败,因为没有传递任何 Forms Cookie
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcV29ya2luZ1xnYXRvci5nYXRvcndlYnNlcnZpY2VcU291cmNlXEdhdG9yV2ViU2VydmljZVxhcGlcVmVyaWZ5TG9naW4=?=
Access-Control-Allow-Origin: http://localhost:61496
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Date: Fri, 03 Jul 2015 08:30:10 GMT
Content-Length: 71
{"$id":"1","Message":"Authorization has been denied for this request."}
有人对此有什么想法吗?
为什么响应发送两个
SetCookie
headers 具有相同的 cookie 名称?这似乎……错误且令人困惑。注意不要给 IE 过多的 cookie 数据。您的 cookie 值很长! cookie 限制为 ~4k。这是您域的 cookie 总数。如果超过这个长度,IE 将不会返回。
HTH
您似乎获得了两个身份验证 cookie,这表明您的实施与 ASP.Net 试图为您自动执行的内容发生冲突。
有一个 FormsAuthentication.SetAuthCookie
创建和设置 cookie,我认为这已经应用了,所以:
FormsAuthentication.SetAuthCookie
获取 cookie(已在同一响应中设置)。- 你的
SetAuthenticationCookie
开火了。 - 这会调用
FormsAuthentication.GetAuthCookie
并处理(将 JSON 序列化数据嵌入到新的 cookie 中)原始数据。 - 您调用
HttpContext.Current.Response.Cookies.Add
创建第二个 cookie。 - 两个 cookie 在 header 中以相同的名称 传送
你没有清除原始cookie,.Net不知道如何处理你处理过的cookie。
我想你有两个选择:
- 将您的 JSON 数据拆分到一个完全独立的 cookie 中,并使用不同的名称。
- 从头开始制作您自己的 cookie,不要使用 .Net 的任何
FormsAuthentication
方法。
我个人认为前者是最简单、实施起来最快的。
尝试 cookie 名称可能也值得 - 我不确定所有浏览器都支持 cookie 名称中的句点,但它们都区分大小写。
最后还有一些值得检查的东西 - 它几乎是 never worth setting a cookie's path in .Net,因为 IIS 将 URL 视为不区分大小写,但浏览器都将 cookie 名称视为 case-sensitive。