我有一个 Web 应用程序,其中我的用户已经在 HTTP 中进行了身份验证。 HTTP 身份验证后,我想接收视频通话。对于此任务,我选择了一个 WebSockets 服务器(我编写了一个小的 PHP CLI 脚本)。
有一个问题,我找不到在我的 WebSocket 守护程序上验证已验证用户的方法。 (因为它是 CLI 应用程序,所以每个实例可与多个用户一起使用。)
我认为,获取用户在握手请求中发送到我的 WebSocket 服务器的 header 是个好主意。我解析了 cookie 并使用 session_id()
和 session_start()
创建了一个 session ,但我不能为多个用户执行此操作,只能为一个用户执行此操作。
在许多论坛上,建议通过 JS 发送用户 ID 和一些 key 来识别用户,但这并不安全。也许我可以发送带有散列用户密码的用户 ID,我会将其存储在 html(js 内联常量)中的某个地方?你怎么看?
在 WebSocket 服务器上验证用户身份的最佳方式是什么?请记住,此用户已通过 HTTP 身份验证。
最佳答案
我强烈建议您不要管他们的密码。不要通过 WebSockets 连接传递它。一旦用户通过任何一种方式进行身份验证,就不要再使用他们的密码。
你是对的,你不能在同一服务器实例中为多个用户使用 session_start()
。相反,您必须单独存储用户的数据并将其与他们的 TCP 套接字句柄相关联。 (TCP 套接字句柄是 socket_accept()
返回的值)。
例如,在您的 WebSockets 服务器中,有一个用户类,您可以在其中为每个连接实例化一个新对象。此用户对象将在他们连接时保持他们的状态。
用户通过您的 Web 应用程序身份验证后,发送一个唯一的 cryptographically secure token在 HTTP 响应中,在 HTTP header 中,或在正文中,例如在 HTML header 中的元素属性中,作为 Javascript 中的分配值,或任何对您有意义的地方。还将此唯一值存储在您的 WebSockets 服务器可以访问的某个位置,以及它分配给哪个用户和时间戳。
在客户端 Javascript 中,一旦建立了 WebSockets 连接,就发送安全 token 。
在服务器端,只需将 token 与您的网络脚本存储的 token 进行比较,并确保时间戳是最新的。这将告诉您哪个用户刚刚登录并允许您从数据库中提取他们的偏好。
关于时间戳到期的注意事项:WebSockets 旨在成为一个实时通信系统,在大多数情况下,WebSockets 连接是在页面加载期间或 onload
事件后不久建立的。除非您在打开 WebSockets 连接之前等待用户交互,否则接受超过几分钟的 token 是没有意义的。为避免 session 劫持尝试,请只接受使用特定 token 的第一个连接,不要接受旧 token 。
一旦他们建立连接,只要他们保持连接,您至少可以像使用 $_SESSION 变量一样确定用户的身份。 (可能会发生 TCP 劫持,但攻击者可能已经进行了 MITM 攻击,并且他们的 PHP session 在 TCP 劫持开始之前很久就已经完全受损。)
关于php - 如何使用 php websockets 服务器获取经过身份验证的用户 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18037039/