PHP + socket.io(会话,授权和安全问题)

我有一个工作的PHP应用程序,我想添加实时支持。 我想使用nodejs / socket.io来添加这种function。

我发现的第一个问题是如何在nodejs端正确授权用户(用户已通过PHP会话在php后端进行身份validation)。 在nodejs端使用socket.handshake.header.cookie我可以parsing和获取PHP会话ID,我可以通过redis / memcache / database(取决于我用来保存会话信息)进行身份validation。
当用户只有一个网站的标签页/窗口打开时,一切看起来很酷 – 当有更多的使用session_regenerate_id() ,在nodejs用户authentication与另一个sessionid键,所以我不能区分两个标签除了他们连接的套接字ID用。 当用户注销时,他不应该在任何选项卡上收到任何消息(因为他已经从该浏览器的每个选项卡/窗口注销)。 所以在注销消息(从浏览器刚刚注销PHP的事情发送),我应该删除所有连接到授权用户ID的套接字连接。 但是,如果用户login在两个设备上(如电脑浏览器和iPad游戏)。 在注销一个设备后,他不应该在他注销的设备上收到任何消息,而不是在每个设备上。 如何区分socket.io中不同设备/浏览器的连接? 当然,不使用session_regenerate_id()会很有效,但是如果我真的想要使用这个function,我该怎么办?

我的另一个问题是安全问题(甚至是问题)。 我们假设应用程序中的授权用户可以看到example.com/user1页面(这是user1的新闻提要),并且看不到example.com/user2 (他没有看到它的权限)。 当用户在example.com/user1上时 ,我想让socket.io向浏览器发送更新消息,当用户在example.com/user2上时 ,当然不会发送更新消息。 在socket.io端我可以读取引用地址(据推测,当用户在user2网站上,他没有得到任何socket.io连接)。 问题是: 我应该比较referer地址与node.js端的身份validation用户的权限? 或者也许引用值在node.js方面是安全的? 在node.js端添加另一个数据库检查会降低速度(因为几乎所有的请求都应该在两边同时进行数据库检查 – PHP和node.js)。

或者,也许整个概念的socket.io + PHP应用程序工作我提出的方式是错误的?

UPDATE

我想我find了一个方法来省略第一个问题的问题 – 基本上我只是添加另一个cookie(除了PHPSESSID)fe。 命名为NODESESSID,我在用户授权时生成(使用uniqid())。 现在在node.js端的授权是比较PHPSESSID和NODESESSID(都必须匹配)。 现在,当用户注销时,他将消息注销传递给socket.io,而socket.io将使用NODESESSID断开所有的套接字。 这就像连接重新生成会话ID的好处,而不是重新生成会话ID(但不容易受到会话固定,不是吗?)。

对于你的第二个问题:

Referer不安全,正如评论中提到的那样。

我在我的应用程序中有类似的问题,这是如何为我工作。

首先,我有一个单页面的应用程序,所有的stream量通过套接字,但那不是必要的。 它应该按照您pipe理它的方式与会话一起工作。

在nodejs onConnect我问后端,如果用户进行身份validation,然后将用户标识存储到套接字对象(socket.data),并填充哈希映射直接从用户ID查找套接字。

其次,我使用Redis并订阅来自nodejs的redis列表( 请参阅redis pub / sub )。 PHP的后端推送消息在这个列表中的用户ID来解决这个消息。 nodejs接收这个消息(例如一个新的消息提要项),在提到的hashmap中查找用户标识符,并将其发送给客户端。 所以,用户只能得到他的授权。 然后客户决定如何处理消息。 如果用户在其供稿页面上,则可以添加该项目。 如果用户在某个人身上,则可以简单地在页面上的其他地方添加通知。 它也可能丢弃它。

在PHP的后端网站,这个消息发送到redis每一个事件发生,需要显示生活在一些连接的客户端。 如果user1在user2的提要上发布,则新项目将存储在数据库中,同时将作为消息发送到redis队列中。

这个系统还有助于减less数据库负载,因为nodejs只需要查询数据库以确保连接的用户已经被authentication。

其实,你可以避免使用node.js,并使用phpdaemon ,它用php编写,工作非常好。