为啥我的“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/公共后缀的推理
参考:https://blogs.msdn.microsoft.com/ieinternals/2009/09/18/understanding-domain-names-in-internet-explorer/在设置 cookie 时,网站可以使用 domain 属性指定 cookie 应该发送到哪些主机。浏览器必须阻止尝试设置域属性不以当前页面的私有域结尾的 cookie。否则会导致隐私和安全问题。
隐私:允许不相关的域共享 cookie 可能会导致“超级 cookie”——这些 cookie 被发送给碰巧共享一个公共后缀的多个不相关的组织。 安全性:会话固定攻击,其中一个好站点和一个恶意站点共享一个公共后缀,而恶意站点在公共后缀上设置一个恶意 cookie,以便向好站点发送恶意 cookie。
Google Chromium / Chrome 行为
Google 在其 CookieMonster 类的描述中指出 Chromium(以及 Chrome)使用“eTLD+1”存储 cookie。
参考:https://www.chromium.org/developers/design-documents/network-stack/cookiemonsterCookieMonster 的中心数据结构是 cookies_ 成员,它是一个从域到某些 cookie 集的多映射(单个键允许多个值)。每个 cookie 由 CanonicalCookie() 表示,它包含可以在 cookie 中指定的所有信息(参见图表和 RFC 2695)。设置后,cookie 将被放入此数据结构中,检索涉及搜索此数据结构。该数据结构的关键是没有命名域名注册商(即“google.com”或“bbc.co.uk”,但不是“co.uk”的cookie域的最包容域(最短点分隔后缀) ”或“com”)。这也称为有效***域加一,简称 eTLD+1。
包括 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
Amazon CloudFront 是不是通过 set-cookie 标头?