2.5.3. Session 的 Cookie 域处理
环境
User -> Http2 CDN -> Http2 Nginx -> proxy_pass 1.1 -> Tomcat
背景,默认情况下 tomcat 不会主动推送 Cookie 域,例如下面的HTTP头
Set-Cookie: JSESSIONID=8542E9F58C71937B3ABC97F002CE039F;path=/;HttpOnly
这样带来一个问题,在浏览器中默认Cookie域等于 HTTP_HOST 头(www.example.com),如果网站只有一个域名没有问题,如果想共享Cookie给子域名下所有域名 *.example.com 无法显示。
通过配置Tomcat sessionCookieDomain="example.com" 可以实现推送 Cookie 域
<Context path="" docBase="/www/netkiller.cn/www.netkiller.cn" reloadable="false" sessionCookieName="PHPSESSID" sessionCookieDomain="netkiller.cn" sessionCookiePath="/" />
这样的配置一般用户的需求都可以满足。我的需求中还有一项,在服务器绑定多个域名(二级域名)。问题来了 Tomcat 将始终推送 netkiller.cn 这个域。其他域名无法正确设置Cookie
$ curl -s -I -H https://www.netkiller.cn/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly
$ curl -s -I -H 'Host: www.test.com' https://www.test.com/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly
$ curl -s -I -H 'Host: www.example.com' https://www.example.com/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly
怎样处理需求呢,我两个两个方案,一个方案是在Nginx中配置,另一个方案是在代码中解决。其中Nginx处理起来比较灵活无需开发测试介入,最终选择nginx方案
server {
listen 443 ssl http2 default_server;
server_name _;
location ~ \.(do|jsp|action)$ {
ssi on;
proxy_set_header Accept-Encoding "";
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $domain $host;
if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)$) {
set $domain $2.$3;
}
proxy_cookie_domain netkiller.cn $domain;
}
}
server_name _; 接受任何域名绑定,default_server 将vhost 设置为默认主机。最终测试结果:
$ curl -s -I -H https://www.netkiller.cn/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=netkiller.cn;path=/;HttpOnly
$ curl -s -I -H https://www.example.com/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=example.com;path=/;HttpOnly
$ curl -s -I -H https://www.domain.com/index.jsp | grep Set-Cookie
Set-Cookie: PHPSESSID=4DBAF36AA7B79CE1ACBA8DD67702B945;domain=domain.com;path=/;HttpOnly