我已阅读w3规范@ http://www.w3.org/TR/eventsource/了解EventSource / SSE的工作原理,但我找不到有关如何创建私有流的任何好信息。
基本上,我想创建一种将私有数据发送到特定用户会话的方法。 下面的两个想法似乎都符合我的要求,但我不确定它们有多安全。
实施例;连接到同一个EventSource URL的每个浏览器是否都会收到相同的数据,浏览器会跟踪它想要的事件名称?
var source = new EventSource('/stream');
source.addEventListener('l0ngr4nd0mSessionID', function(e){
console.log('Received a private message:', e.data);
});
没有事件名称l0ngr4nd0mSessionID的人是否能够收到此消息?
这个案子怎么样;
var source = new EventSource('/stream/l0ngr4nd0mSessionID ');
source.addEventListener('private', function(e){
console.log('Received a private message:', e.data);
});
这些示例和设置withCredentials选项一样好吗? 我的sse服务器是一个独立的服务器,而不是主要的web服务器,所以我最好不要使用withCredentials发送身份验证数据,而是使用其中一个示例。
答案 0 :(得分:12)
每个流都是私有的。 SSE不是广播技术(除非您故意实施它)。而是为每个浏览器客户端提供与服务器的专用套接字连接。您的服务器将使用并发事件处理程序来处理该客户端,并将选择它要发送给该客户端的信息。您也可以获得该客户端的cookie,因此可以识别他们的会话,基本身份验证也可以。
当涉及CORS时,一切都变得复杂得多,即如果您的SSE服务器与提供HTML的源服务器不同。这就是你描述的情况。您的服务器将必须发送回"Access-Control-Allow-Origin: *"
,但如果您愿意发送该唯一会话ID,则无需使用withCredentials。但请注意,您不会获得cookie或基本身份验证数据。
回到你的问题,第一个例子是坏的。这意味着您的服务器正在向所有客户端广播私有数据。除了隐私问题,这也是带宽的可怕浪费。
您的第二种方法更好:您使用URL中的某些内容来标识用户应该接收的数据,而不是使用Cookie或身份验证。请注意,知道此URL的任何人都可以获得相同的数据。 SSL无济于事。我猜测您的会话ID是他们登录主网站时获得的,并且在注销时会过期。在大多数情况下,我认为这是足够好的:黑客必须在相对较短的访问窗口中遇到很多麻烦。换句话说,使用社交工程更容易获取用户的身份验证细节。但您需要自己进行风险/收益评估。
最安全的方法是将SSL与cookie或基本身份验证一起使用。如果Web服务器和流服务器是相同的 origin ,这很容易;否则你需要使用withCredentials
。