我在一台机器上运行两个HTTP服务。我只是想知道它们是否共享cookie,或者浏览器是否区分这两个服务器套接字。


它是可选的。

可以指定端口,因此cookie可以是特定于端口的。这是不必要的,web服务器/应用程序必须关心这个。

来源:德文维基百科文章,RFC2109,第4.3.1章

这是cookie SOP(同源策略)中的一个很大的灰色区域。

理论上,可以在域中指定端口号,cookie不会被共享。实际上,这在几种浏览器中都不起作用,您还会遇到其他问题。因此,只有当你的网站不是面向大众的,并且你可以控制使用什么浏览器时,这才可行。

更好的方法是为相同的IP获取2个域名,并且不依赖端口号进行cookie。

根据RFC2965 3.3.1(浏览器可能遵循也可能不遵循),除非通过Set-Cookie报头的port参数显式指定端口,否则cookie可能会或可能不会被发送到任何端口。

谷歌的浏览器安全手册说:默认情况下,cookie范围仅限于当前主机名上的所有url,而不绑定端口或协议信息。没有办法将cookie限制为单个DNS名称[…]同样,也没有办法将它们限制在特定的端口上。(另外,请记住,IE根本不会将端口号考虑到其同源策略中。)

因此,在这里依赖任何定义良好的行为似乎都不安全。

解决这个问题的另一种方法是使会话cookie的名称与端口相关。例如:

Mysession8080用于运行在端口8080上的服务器 Mysession8000用于运行在端口8000上的服务器

您的代码可以访问webserver配置,以找出您的服务器使用哪个端口,并相应地命名cookie。

请记住,您的应用程序将接收这两个cookie,您需要请求与您的端口对应的那个cookie。

在cookie名称中不需要有确切的端口号,但这样更方便。

通常,cookie名称可以编码特定于您使用的服务器实例的任何其他参数,因此可以通过正确的上下文对其进行解码。

在IE 8中,cookie(仅针对本地主机进行验证)在端口之间共享。在FF 10中,它们不是。

我公布了这个答案,以便读者至少有一个具体的选项来测试每个场景。

这是一个非常老的问题,但我想我可以添加一个我使用过的变通方法。

我的笔记本电脑上运行着两个服务(一个在端口3000上,另一个在端口4000上)。 当我在(http://localhost:3000和http://localhost:4000)之间跳转时,Chrome会传入相同的cookie,每个服务都不会理解cookie并生成一个新的cookie。

我发现如果我访问http://localhost:3000和http://127.0.0.1:4000,这个问题就消失了,因为Chrome为localhost保留了一个cookie,为127.0.0.1保留了一个cookie。

再说一次,没有人会在意这一点,但这对我的情况来说很简单,也很有帮助。

当前的cookie规范是RFC 6265,它取代了RFC 2109和RFC 2965(这两个RFC现在都被标记为“Historic”),并规范了cookie的实际用法语法。它明确指出:

简介 ... 由于历史原因,cookie包含许多安全和隐私方面的缺陷。例如,服务器可以指示给定的cookie用于“安全”连接,但当存在活动网络攻击者时,secure属性不提供完整性。类似地,给定主机的cookie在该主机上的所有端口上共享,即使web浏览器使用的通常的“同源策略”隔离了通过不同端口检索的内容。

还有:

8.5. Weak Confidentiality Cookies do not provide isolation by port. If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port of the same server. If a cookie is writable by a service on one port, the cookie is also writable by a service running on another port of the same server. For this reason, servers SHOULD NOT both run mutually distrusting services on different ports of the same host and use cookies to store security sensitive information.

我在同一台机器上运行(并尝试调试)两个不同的Django应用程序时遇到了类似的问题。

我用这些命令运行它们:

./manage.py runserver 8000
./manage.py runserver 8001

当我登录了第一个,然后在第二个,我总是注销了第一个,反之亦然。

我在我的/etc/hosts上添加了这个

127.0.0.1    app1
127.0.0.1    app2

然后我用这些命令启动了这两个应用程序:

./manage.py runserver app1:8000
./manage.py runserver app2:8001

问题解决了:)