1. 问题描述
同一套前端ERP程序,部署了多个账套。两个账套的协议、ip相同,端口不同。
http://xxx.xx.x.xxx:8002
http://xxx.xx.x.xxx:9003
当同一用户在同一浏览器(Chrome)打开这两个不同端口的程序进行操作时,出现跳转到登录页面的问题。
2. 排查过程
经排查,发现是出现了Cookie被覆盖的问题。排查过程如下:
- 登录
8002
后,获取到 CookiesessionId=b130ffea-c9dc-46cf-b37d-e28db9ce8ea3;
。此时8002
标签页可与服务端正常通讯。 - 新开一个标签页,登录
9003
程序,获取到 CookiesessionId=b74fe72d-822e-410a-965f-125540156fd7;
。此时9003
标签页可以与服务端正常通讯。 - 切换到
8002
标签页, 此时与后端通讯,请求携带的 Cookie 变成了9003的cookiesessionId=b74fe72d-822e-410a-965f-125540156fd7
。程序跳转到登录页面。
前端程序是没有对 Cookie 做任何操作的。说明在第二个标签页即 9003
登录后,第一个标签页 8002
的 Cookie 被覆盖了。
3. 相关知识
查找资料后,知道 Cookie 相对于LocalStorage 和 SessionStorage ,是不会对端口做区分的。
1.介绍
由于历史原因,cookie包含许多安全和隐私信息。例如,服务器可以指示给定的cookie用于“安全”连接,但Secure属性在存在活动网络攻击者时不提供完整性。 同样,给定主机的cookie在该主机上的所有端口之间共享,即使Web浏览器使用的通常的“同源策略”隔离了通过不同端口检索的内容。
…8.5 弱机密性
Cookie不提供端口隔离。如果cookie在一个端口上运行的服务可读,则cookie也可由在同一服务器的另一个端口上运行的服务读取。如果cookie在一个端口上可由服务写入,则cookie也可由在同一服务器的另一个端口上运行的服务写入。出于这个原因,服务器不应该在同一主机的不同端口上运行相互不信任的服务,并使用cookie来存储安全敏感信息。
[谷歌] 浏览器安全手册
默认情况下,cookie范围仅限于当前主机名上的所有URL - 而不是绑定到端口或协议信息。
其它
在http://localhost:3000和http://localhost:4000之间跳转时,Chrome会传入相同的cookie,每个服务都无法理解cookie并生成新的cookie。但如果访问http://localhost:3000和http://127.0.0.1:4000,就不会有问题。因为Chrome浏览器保持一个cookie本地主机,一个用于127.0.0.1
4. 解决方案
- 使用两个浏览器分别打开页面
- 摒弃cookie,使用sessionStorage或localstorage保存用户token,请求头使用
token:b74fe72d-822e-410a-965f-125540156fd7
5. 感想
遇到这个问题,首先想到的是去mdn查cookie的作用域,了解到影响Cookie 的作用域两个属性:Domain 和 Path 。在这个问题中我们并没有设置Domain和Path,我们查Path的默认值是orgin相同域(浏览器同源策略),这使我很迷茫,现在端口不同,不就是不同域吗?答案就是上面说的:Cookie的作用域不区分协议和端口,也就是说只要ip地址相同,协议不同或端口不同,cookie都会覆盖。