[英]Why isn't my “Set-Cookie” response header getting translated into an actual cookie?
我正在使用Java 8,Wildfly 11,Spring 4和Apache 2.4。 我有这个Java代码来设置会话cookie
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被创建。 任何见解都表示赞赏,
Cookie域必须是特定于您的组织的专用域,而不是许多组织使用的公共域。
在这种情况下,您正在使用的AWS域名.compute-1.amazonaws.com
未被设置,因为浏览器认为这是一个公共域,特别称为“有效顶级域(eTLD)”,“扩展顶级域名“和”公共后缀“。 常见顶级域名(TLD)包括.com
, .net
和.org
等“通用TLD”(gTLD)和.us
和.uk
等“国家/地区代码顶级域名(ccTLD)”。 借助公共云,浏览器现在也将流行的共享云域视为“有效TLD”,包括来自AWS的许多域,例如您尝试使用的域。
要设置Cookie,您需要将Cookie域设置为私有域,Google称之为“有效顶级域名加1”(eTLD + 1),这意味着您的有效顶级域名加上一个子域名,例如您的整个域名此实例中的限定主机名 - ec2-27-123-206-78.compute-1.amazonaws.com
。 Microsoft使用术语“Public Suffix plus one”(PS + 1)来满足相同的要求。
Mozilla基金会推断排除eTLD /公共后缀
- 避免为高级域名后缀设置破坏隐私的“超级英雄”
- 突出显示用户界面中域名最重要的部分
- 按站点准确排序历史记录条目
Microsoft排除eTLD /公共后缀的推理
设置cookie时,网站可以使用domain属性指定cookie应发送到哪些主机。 浏览器必须阻止尝试设置cookie,其中domain属性不以当前页面的私有域结束。 不这样做会导致隐私和安全问题。
- 隐私:允许不相关的域共享cookie可能会导致“超级cookie” - 发送给碰巧共享公共后缀的多个不相关组织的cookie。
- 安全性:会话固定攻击,其中一个好的站点和一个邪恶的站点共享一个公共后缀,邪恶的站点在公共后缀上设置一个恶意cookie,以便Good站点被发送邪恶的cookie。
Google Chromium / Chrome行为
谷歌表示Chromium(以及Chrome)在其CookieMonster类的描述中使用“eTLD + 1”存储cookie。
CookieMonster的中心数据结构是cookies_成员,它是从域到一组cookie的多图(允许单个键的多个值)。 每个cookie由CanonicalCookie()表示,其中包含可以在cookie中指定的所有信息(参见图表和RFC 2695)。 设置时,将cookie放入此数据结构中,检索涉及搜索此数据结构。 此数据结构的关键是cookie域的最具包容性的域(最短点分隔后缀),该域名未命名域名注册商(即“google.com”或“bbc.co.uk”,但不是“co.uk” “或”com“)。 这也称为有效顶级域加1或eTLD + 1,简称为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
注意:我刚注意到saurav kumar在评论中发布了Mozilla链接。
您尝试为Amazon EC2实例设置Cookie的问题。 从一方面来说,这是不可能的,因为它是公共后缀的一部分,如上所述,出于安全原因,你不能这样做。
从另一方面来说,没有任何意义,因为这个公共地址:“ec2-27-123-206-78.compute-1.amazonaws.com/context/login”是动态的,并不适合你。 它是DNS代理,目前为您保留。 如果要从EC2实例设置cookie,则应设置自己的主机名的域名,这些域名位于EC2实例的前面。
request.getServerName()
这将为您提供EC2的当前服务器名称。 但是,举例来说,如果你的nginx代理请求,你应该得到“主机”头( 1 , 2 )。
如果响应头包含set-cookie
,则必须已创建cookie。 尝试删除set-domain,让它默认。 同时尝试设置最大年龄。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.