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