关于前后端写入Cookie时domain的一个问题
本文由 小茗同学 发表于 2017-10-31 浏览(12923)
最后修改 2022-03-23 标签:cookie

正文

前端

先假设有如下setCookie方法:

function setCookie(name, value, day, path, domain)
{
	day = day || 30;
	path = path || '/';
	var str = name + '=' + value + '; ';
	if(day) str += 'expires=' + new Date(Date.now() + day * 24 * 3600 * 1000).toGMTString() + '; ';
	if(path) str += 'path=' + path + '; ';
	if(domain) str += 'domain=' + domain;
	document.cookie = str;
},

假设当前域名为blog.xiaoming.com,经测试发现,JS在写入cookie时:

xei.setCookie('test1', 'abcd', 30, '/'); // 成功,默认写入当前域名
xei.setCookie('test2', 'abcd', 30, '/', 'blog.xiaoming.com'); // 成功,前面追加一个“.”
xei.setCookie('test3', 'abcd', 30, '/', 'abcd.xiaoming.com'); // 写入不成功
xei.setCookie('test4', 'abcd', 30, '/', '.xiaoming.com'); // 成功
xei.setCookie('test5', 'abcd', 30, '/', 'xiaoming.com'); // 成功,前面追加一个“.”
xei.setCookie('test6', 'abcd', 30, '/', 'www.qq.com'); // 写入不成功

结果:

说明:

  • 不传domain,默认当前域名;
  • 只要传了domain,则会强制在前面加上一个.,不管是一级还是二级域名;
  • domain只能“小于等于”当前域名,否则写入不成功;

特别注意

另外发现,.xiaoming.com下的cookie会出现在blog.xiaoming.com页面(也就是说可以被下级域名正确获取到),但是,xiaoming.com下的cookie不会出现在它的子域名页面!这个是以前没有注意的!

2022-03-23更新:貌似这个结论有问题,待具体验证;

所以特别注意:

要想写入的cookie被其子域名共享,必须保证域名前面有一个英文的.,但由于只要显式传了domain会自动追加一个“.”,所以只要手动传了domain,那么子域名自动会共享

后台

以Java为例:

private void setCookie(HttpServletResponse response, String name, String value, String domain, String path, Integer days)
{
	Cookie cookie = new Cookie(name, URLUtil.encode(value));// 防止中文乱码问题
	cookie.setDomain(domain);
	cookie.setPath(path);
	cookie.setMaxAge(60 * 60 * 24 * days);
	response.addCookie(cookie);
}

经测试同样存在和前端一样的问题:不传domain则默认当前域名,传了则强制在前面加一个.

关于转发setCookie

假设有原始地址:www.a.com/set-cookie.json, 里面有代码:

this.set('set-cookie', 'mgtest1=11111; domain=www.a.com; Path=/; HttpOnly')
this.set('set-cookie', 'mgtest2=22222; Path=/; HttpOnly')

注意,nodejs好像不可以这样写入多个cookie,后面的会把前面的覆盖,这里这么写只是为了演示。

现在需要把这个地址转发:

# lightproxy配置
www.b.com www.a.com

浏览器访问 www.b.com/set-cookie.json 的时候,真正写入到www.b.com的只有mgtest2mgtest1写入到www.a.com上面去了。

分析:

  • 如果setCookie的时候指定了某个domain,那么cookie只会写入到这个域名,即便通过nginx等工具转发之后仍然如此;
  • 如果setCookie的时候没有指定域名,那么浏览器访问的是哪个地址就写入到哪个地址;
  • 所以如果想让转发的时候cookie能写入成功的话:
    • 建议直接不指定域名,这是最简单的做法。
    • 如果已经指定了域名无法修改,则可以通过proxy_cookie_domain等类似配置进行修改,nginx的这个命令可以替换set-cookie里面的domain值;