Websockets 控制用户访问

Posted

技术标签:

【中文标题】Websockets 控制用户访问【英文标题】:Websockets control user access 【发布时间】:2016-05-08 19:08:58 【问题描述】:

我目前在我的 php 项目 [Ratchet, Symfony] 中使用 Websockets。当用户登录时,他会自动连接到 websocket 连接中的通道。我能够将消息推送到频道并在客户端上接收并显示它们。因此,在登录后连接到 websocket 时管理对 websocket 的访问是没有问题的。假设我们有以下情况,我在身份验证时遇到了问题:

    用户已登录并有权访问频道 用户在另一个选项卡上注销或清除其缓存 在用户重新加载他的页面之前,他仍然会收到 websocket 通道的消息。

我检查了用户在使用 websockets 而不是 ajax 时仍然登录到 websocket 端 symfony 会话。当我使用 ajax demo -request 检查相同的内容时,用户不再登录。这是主要问题,websocket session 与 symfony session 没有同步好,因为在 symfony session 中,用户已注销,但在 Websocket 上,他仍然处于登录状态。

最初,我尝试了以下方法来避免上述情况:

    当用户通过 websocket 通道收到新消息时,我首先使用远程调用程序检查用户是否仍然登录,通过从服务器发送标志 true 或 false (这就是不同步会话的问题发生的地方) 当标志为假时,我从频道中取消订阅用户 当标志为真时,我处理 websocket 通道的回调。

总的来说,我认为这种方法会很好 (?) ,但我看到的问题是不同步的会话。当推送到达它时,如何同步它或强制 websocket 通道检查 cookie/再次发送它?你如何处理这种情况?

【问题讨论】:

【参考方案1】:

我个人是如何解决这个问题的。 我保存了我在数据库中打开时拥有的每个 connectionId。

然后我检查了哪些连接应该接收哪个通道,并且只向应该接收它的那些发送消息。

之后,一旦您的问题出现:用户注销,然后我从具有打开连接的数据库中删除该用户,并且这些频道的每条新消息都不会再发送给该用户。

编辑: 为了解决这里提出的问题:用户刷新了他/她的缓存/cookies,但连接仍然打开,如何确保连接仍然安全?

回答:如果用户刷新他/她的缓存,socketconnection 将保持存在,尽管用户会在浏览器刷新/重定向后关闭它。这里的安全问题是不存在的,因为用户在会话开始时以正确的方式连接,然后清除了他们的缓存,因此他们被注销了。

如果用户不怀好意,那么一开始就不应该建立连接。

【讨论】:

那么用户将失去他的会话,尽管您仍然在服务器上拥有会话。因此,您可以将会话重新发送给用户,或者在用户再次登录后创建一个新会话,并将其保存在以前的 connectionId 上。您当前以何种方式将会话存储在 cookie 中? 我使用 PdoSessionHandler 进行存储。在我看来,您的解决方案无法处理用户打开浏览器、清除其缓存/cookies 的情况。因为在他重新加载页面之前,他仍然会通过 websocket 获取消息?用户只是在客户端站点上失去了会话,但在 websocket 端,他仍然是经过身份验证的。 我想通过读取cookie的会话ID在远程过程调用中发送会话ID,然后检查该值是否与websocket服务器中存储的会话ID匹配。如果不是,他就不再被认证(至少在他声称的身份上)。但这是不可能的,因为我无法从浏览器中读取安全 cookie.. 因此您无法从 cookie 中读取 sessionId/connectionId 并将其与打开的 websocket 会话进行比较,如果它们相同则仅使用接收到的数据? 是的,这就是我的观点,因为没有人能够再使用它或者能够以某种方式劫持他/她的连接。当然,除了浏览器本身,但该用户已经拥有访问权限,因此该用户没有必要“破解”他已经允许的连接

以上是关于Websockets 控制用户访问的主要内容,如果未能解决你的问题,请参考以下文章

如何在 websocket 控制器中检索当前登录的用户

XSockets / WebSockets 无法从主机以外的其他机器访问

无法访问 xampp-vm 上的 laravel-websockets 仪表板

如何访问使用 websockets 发送的烧瓶中的 formData?Flask-SocketIO

MySQL访问控制和用户管理

vsftpd服务详解(匿名用户访问,本地用户访问,指定用户访问控制,虚拟用户)