3

我有一个 Web 应用程序,我的用户已经在 HTTP 中进行了身份验证。HTTP 身份验证后,我想接收视频通话。对于这个任务,我选择了一个 WebSockets 服务器(我写了一个小的 PHP CLI 脚本)。

有一个问题,我找不到在我的 WebSocket 守护程序上对经过身份验证的用户进行身份验证的方法。(因为它是 CLI 应用程序,它可以与每个实例的许​​多用户一起使用。)

我认为,最好将用户在握手请求中发送的标头发送到我的 WebSocket 服务器。我解析了 cookie 并使用 and 创建了一个会话session_id()session_start()但我不能为多个用户执行此操作,只能为一个用户执行此操作。

在许多板上,建议通过 JS 发送用户 ID 和一些密钥来识别用户,但这并不安全。也许我可以发送带有散列用户密码的用户 ID,我将其存储在 html 中的某处(js 内联常量)?你怎么看?

在 WebSocket 服务器上对用户进行身份验证的最佳方法是什么?请记住,该用户已经通过 HTTP 进行了身份验证。

4

1 回答 1

0

我强烈建议您不要管他们的密码。不要通过 WebSockets 连接传递它。一旦通过任何一种方式对用户进行了身份验证,就不要再使用他们的密码了。

您是对的,您不能session_start()在同一服务器实例中使用多个用户。相反,您必须单独存储用户的数据并将其与他们的 TCP 套接字句柄相关联。(TCP 套接字句柄是返回的值socket_accept())。

例如,在您的 WebSockets 服务器中,有一个用户类,您可以在其中为每个连接实例化一个新对象。此用户对象将在连接时保持其状态。

在用户向您的 Web 应用程序进行身份验证后,在 HTTP 响应中发送一个唯一的、加密安全的令牌,可以在 HTTP 标头中,也可以在正文中(例如 HTML 标头中元素的属性中)作为 Javascript 中的分配值,或任何对您有意义的地方。还要将此唯一值存储在您的 WebSockets 服务器可以访问的某个位置,以及分配给哪个用户和时间戳。

在客户端 Javascript 中,一旦建立 WebSockets 连接,就发送安全令牌。

在服务器端,只需将令牌与您的 Web 脚本存储的令牌进行比较,并确保时间戳是最新的。这将告诉您哪个用户刚刚登录,并允许您将他们的偏好从数据库中提取出来。

关于时间戳过期的说明:WebSockets 是一个实时通信系统,在大多数情况下,WebSockets 连接是在页面加载期间或onload事件后不久建立的。除非您在打开 WebSockets 连接之前等待用户交互,否则接受超过几分钟的令牌是没有意义的。为避免会话劫持尝试,请仅接受第一个连接以使用特定令牌,不要接受旧令牌。

一旦他们连接,您至少可以确定用户的身份,就像您使用 $_SESSION 变量一样,只要他们保持连接。(可能会发生 TCP 劫持,但攻击者已经进行了 MITM 攻击,并且他们的 PHP 会话在 TCP 劫持开始之前很久就已经完全受损。)

于 2015-06-17T00:28:40.567 回答