为啥我的“Set-Cookie”响应标头没有被翻译成实际的 cookie?

Posted

技术标签:

【中文标题】为啥我的“Set-Cookie”响应标头没有被翻译成实际的 cookie?【英文标题】:Why isn't my "Set-Cookie" response header getting translated into an actual cookie?为什么我的“Set-Cookie”响应标头没有被翻译成实际的 cookie? 【发布时间】:2018-10-22 07:57:36 【问题描述】:

我正在使用 Java 8、Wildfly 11、Spring 4 和 Apache 2.4。我有这个设置会话 cookie 的 Java 代码

cookie = new Cookie(SESSION_ID_KEY, sessionId);
...
final String domain = request.getServerName().indexOf(".") == -1 ? request.getServerName() : request.getServerName().substring(request.getServerName().indexOf(".") + 1, request.getServerName().length());
if (!StringUtils.equals(domain, "localhost") && !isIpAddress)

            cookie.setDomain(domain.indexOf('.') > -1 ? "." + domain : domain);
   // if
final String contextPath = request.getContextPath() != null && request.getContextPath().endsWith("/") ? request.getContextPath().substring(0, request.getContextPath().length() - 1): request.getContextPath();
cookie.setPath(contextPath);
System.out.println("setting domain " + domain + " and context path:" + contextPath);
response.addCookie(cookie);

我注意到我的浏览器中没有创建这个 cookie。然后我查看 Postman,并注意到没有创建 cookie,尽管我看到了这些响应标头...

Set-Cookie →MY.SESSION.ID=10c25010534c4dd3900851ec1dfaebeb; path=/context; domain=.compute-1.amazonaws.com
Set-Cookie →closeTrialNoteDialog=""; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:00 GMT

似乎在未创建 cookie 时,响应标头仍包含此 Set-Cookie 标头。但是,我无法判断上述任何一个有什么问题,这会阻止创建 cookie。任何见解表示赞赏,

【问题讨论】:

***.com/questions/1062963/…,是一个类似的问题。另外,为什么要在公共域级别设置 cookie? 最大年龄=0; Expires=Thu, 01-Jan-1970 00:00:00 GMT ? 【参考方案1】:

Cookie 域必须是专用域,特定于您的组织,而不是许多组织使用的公共域。

在这种情况下,您正在使用的 AWS 域 .compute-1.amazonaws.com 未设置,因为浏览器将其视为公共域,具体称为“有效***域 (eTLD)”、“扩展***域”域”和“公共后缀”。常见***域 (TLD) 包括“通用 TLD” (gTLD),例如 .com.net.org,以及“国家代码 TLD”(ccTLD),例如 .us.uk。借助公共云,浏览器现在还将流行的共享云域视为“有效的 TLD”,包括来自 AWS 的多个域,例如您尝试使用的域。

要设置您的 cookie,您需要将您的 cookie 域设置为私有域,谷歌称之为“有效***域加一个”(eTLD+1),这意味着您的有效***域加一个子域,例如在这种情况下,您的完整主机名 - ec2-27-123-206-78.compute-1.amazonaws.com。 Microsoft 使用术语“公共后缀加一”(PS+1) 来表示相同的要求。

Mozilla 基金会排除 eTLD/公共后缀的推理

避免为高级域名后缀设置损害隐私的“超级cookies” 在用户界面中突出显示域名中最重要的部分 按站点准确排序历史条目
参考:https://publicsuffix.org/(Mozilla 基金会)

Microsoft 排除 eTLD/公共后缀的推理

在设置 cookie 时,网站可以使用 domain 属性指定 cookie 应该发送到哪些主机。浏览器必须阻止尝试设置域属性不以当前页面的私有域结尾的 cookie。否则会导致隐私和安全问题。

隐私:允许不相关的域共享 cookie 可能会导致“超级 cookie”——这些 cookie 被发送给碰巧共享一个公共后缀的多个不相关的组织。 安全性:会话固定攻击,其中一个好站点和一个恶意站点共享一个公共后缀,而恶意站点在公共后缀上设置一个恶意 cookie,以便向好站点发送恶意 cookie。
参考:https://blogs.msdn.microsoft.com/ieinternals/2009/09/18/understanding-domain-names-in-internet-explorer/

Google Chromium / Chrome 行为

Google 在其 CookieMonster 类的描述中指出 Chromium(以及 Chrome)使用“eTLD+1”存储 cookie。

CookieMonster 的中心数据结构是 cookies_ 成员,它是一个从域到某些 cookie 集的多映射(单个键允许多个值)。每个 cookie 由 CanonicalCookie() 表示,它包含可以在 cookie 中指定的所有信息(参见图表和 RFC 2695)。设置后,cookie 将被放入此数据结构中,检索涉及搜索此数据结构。该数据结构的关键是没有命名域名注册商(即“google.com”或“bbc.co.uk”,但不是“co.uk”的cookie域的最包容域(最短点分隔后缀) ”或“com”)。这也称为有效***域加一,简称 eTLD+1。

参考:https://www.chromium.org/developers/design-documents/network-stack/cookiemonster

包括 amazonaws.com 在内的域名列表

您可以在 Mozilla 的 PublicSuffix.org 上发布的源代码中查看 Firefox 使用的有效***域列表。 Google CookieMonster 页面也引用了 PublicSuffix.org。此列表包括许多 AWS 域,包括您尝试用于 EC2 的域,由 Amazon 提交。

// Amazon Elastic Compute Cloud : https://aws.amazon.com/ec2/
// Submitted by Luke Wells <psl-maintainers@amazon.com>
*.compute.amazonaws.com
*.compute-1.amazonaws.com
*.compute.amazonaws.com.cn
us-east-1.amazonaws.com
参考:https://publicsuffix.org/list/effective_tld_names.dat

注意:我刚刚注意到 saurav kumar 在评论中发布了 Mozilla 链接。

【讨论】:

【参考方案2】:

您尝试为 Amazon EC2 实例设置 Cookie 的问题。 一方面这是不可能的,因为它是公共后缀的一部分,如上所述,并且出于安全原因,您不能这样做。

从另一方面来说,这没有任何意义,因为这个公共地址:“ec2-27-123-206-78.compute-1.amazonaws.com/context/login”是动态的,对你来说不是固定的.它是当前为您保留的 DNS 代理。 如果你想从 EC2 实例设置 cookie,你应该设置你自己的主机名的域名,在 EC2 实例的前面。

request.getServerName()

这将为您提供 EC2 的当前服务器名称。但是,例如,如果你使用 nginx 代理请求,你应该得到 'Host' 标头(1,2)。

【讨论】:

【参考方案3】:

如果响应头包含set-cookie,则必须创建cookie。尝试删除 set-domain,让它默认。也尝试设置最大年龄。

【讨论】:

如果我删除“setDomain”,cookie 就会出现。但是,我确实需要那里的域,所以我想弄清楚我们做错了什么,以便我们可以在 cookie 中有一个域并设置 cookie。 你能分享一下当cookie出现时你请求的URL是什么。 (删除域后) 发出请求的 URL 是“ec2-27-123-206-78.compute-1.amazonaws.com/context/login” 好吧。您不能为 .compute-1.amazonaws.com 设置 cookie,它是一个公共域。如果您碰巧在compute-1.amazon.com 上浏览了两个以上的站点,您将一直覆盖彼此的会话。您应该将 cookie 域设置为 ec2-27-123-206-78.compute-1.amazonaws.com。你的用例是什么,为什么不能让域默认或使用服务器名称作为域。 不是公共域,而是公共后缀。我的错。无论如何:请点击链接:https://publicsuffix.org 和实际列表:https://github.com/publicsuffix/list/blob/master/public_suffix_list.dat。不幸的是,您无法以编程方式解决它。它是一个由 Mozilla 维护的列表。

以上是关于为啥我的“Set-Cookie”响应标头没有被翻译成实际的 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

未在浏览器中创建响应标头中的 Set-Cookie - 使用 http POST

为啥 Chrome 会忽略 Set-Cookie 标头?

Amazon CloudFront 是不是通过 set-cookie 标头?

从响应标头角度获取 set-cookie 值

Spring 何时发回 XSRF-TOKEN set-cookie 响应标头?

为啥浏览器会忽略 set-cookie 标头,并且未使用 fetch 从 Ajax 调用中保存 cookie?