2017-03-08 52 views
0

在我发送一个不同的主机上的WebSocket连接到API服务器:连接到API时,没有持续会话不同的主机

new WebSocket("ws://localhost:3000") 

而我的前端托管在localhost:8080

在我的API的websocket连接处理程序中我可以在session(与Sinatra的enable :sessions)上设置密钥,但每次刷新html页面时,数据都会丢失。

对于前端与服务器共享同一主机的会话是否存在一些要求?或者有什么方法可以解决这个问题?顺便说一句,前端运行在Webpack服务器(Node)上。

我也尝试添加一个cross_origin津贴API的根路径http://localhost:3000,然后做这个客户端(在CoffeeScript的这个例子):

$.get "http://localhost:3000", -> 
    new Websocket("ws://localhost:3000") 

我的想法是,也许需要的会议将“初始化“通过http://而不是ws://,但它也没有工作。该会话也不适用于$.get "http://localhost:3000"请求。刷新页面显示会话每次都会清除。

+1

会话将基于cookie,因此问题可能是会话cookie的持久性。当您使用与网页不同的主机/端口时,您的会话cookie就成为所谓的第三方cookie,并且第三方cookie有不同的安全规则和设置。我猜想你的设置或加载项阻止了第三方cookie的持久性。简单的webSockets本身可以很好地处理跨源连接,但是如果你在建立时试图附加一个会话cookie,那就需要持久化cookie。 – jfriend00

+0

那么我要向客户端或服务器添加代码? –

+0

您必须先查看第三方Cookie是否由您的客户保留。如果不是,那么您必须修复客户端中的设置,以保留它们或停止使用单独的来源,这样您就不会违反第三方Cookie设置。 – jfriend00

回答

1

正如我们在评论中所讨论的,您可能在浏览器中遇到第三方会话cookie问题。

下面是一个可以用来解决它的方案。

  1. 客户端首次使webSocket连接。
  2. 服务器发回一个带有sessionID的webSocket消息。
  3. 客户端将会话ID存储在第一方cookie(例如主机网页中的cookie)中。
  4. 用户点击刷新。
  5. 网页检查主机页面的cookie中是否有webSocket会话cookie。如果是这样,它为webSocket连接构造一个URL,其中包含会话ID`new Websocket(“ws:// localhost:3000?session = xyslkfas”)
  6. 当服务器接受webSocket连接时,它会检查查询参数以查看如果已经指定了一个会话。如果是这样,并且该会话仍然有效,它将连接到该会话。如果不是,则会创建一个新会话并返回步骤2.
+0

**注意**:除非每个*连接都会轮询会话ID,否则此方法会带来安全风险。否则,会话ID会被大多数中间人的请求记录下来,并且很容易被劫持。诚然,会话开始时并不安全,但我会避免将任何信息附加到请求URL。 – Myst

+0

@Myst - 好点。 sessionID应该总是过期并且不会特别长。或者,一旦会话ID用于重新登录,可以创建一个新的会话并将其发送回客户端,就像在步骤2中一样,旧的会失效。或者,您可以接受没有带重新连接查询参数布尔值的sessionID的webSocket连接,然后在允许处理任何其他消息(从而避免记录)之前几秒钟内发送该证书。有很多方法可以使其更安全,这取决于您需要/希望保护的内容。 – jfriend00

+0

@Myst - 另外,考虑到OP在这里根本不谈论任何认证,我认为这个sessionID只是让服务器可以将重新连接的webSocket与前一个会话信息相关联。所以,这似乎并不是一个经过验证的连接,所以安全性不一定是这里的主要问题。如果有认证信息,那么重新连接可以提交认证信息并以这种方式解决问题。 – jfriend00