Javascript Socket.io-实现专用消息的用户套接字关联映射

Javascript Socket.io-实现专用消息的用户套接字关联映射,javascript,node.js,sockets,websocket,socket.io,Javascript,Node.js,Sockets,Websocket,Socket.io,我正在尝试使用socket.io创建一个专用消息传递系统 为了将用户与其套接字相关联,大多数网站建议如下: var people = {}; client.on('connection', function(socket) { //join the server socket.on('add user', function(user_id) { //create user-socket map people[user_id] = socket.

我正在尝试使用socket.io创建一个专用消息传递系统

为了将用户与其套接字相关联,大多数网站建议如下:

var people = {};

client.on('connection', function(socket) {

    //join the server
    socket.on('add user', function(user_id) {
        //create user-socket map
        people[user_id] = socket.id;
    });

});
 client side :

     var c = io.connect('http://localhost:3000/', { query: "userId=value01" });



server side :
 // extract userId param from connected url
 io.on('connection', function(socket) {
      var socket_param_userId = socket.handshake['query']['userId'];
      console.log(socket_param_userId);  //show value01
});
在我看来,上述代码的问题在于
用户id
是从客户端发送的,因此如果用户以某种方式修改它并发送另一个
用户id
将发生模拟


此外,我无法访问
客户机下的
req.user.\u id
。在('connection')…
上,那么我应该如何从服务器端获取
用户id
?我使用的是node.js、passport和express。

var-people
将在同一进程中访问

当您希望使用多个套接字服务器进行扩展并在它们之间进行平衡时,这种将人员对象保留在本地的想法将毫无帮助

为身份验证创建
authenticate
事件,并设置
socket.userId
socket.isAuthenticate=true
标志。在其他事件中,如果socket.isAuthenticate为false,则将其踢出

使用“socket.io redis”adpater在多个socket.io服务器之间进行通信(因此,当server1中的user1向server2中的user2发送消息时,就会起作用)

对于socket-用户与多进程的关联,您可以使用其用户ID加入文件室,在身份验证时,加入文件室,如
socket.join('myuserId');


当向该用户发送消息时,您可以使用
io.to('myuserId').emit('message','Hi How you?):

您可以像这样发送套接字连接的附加数据:

var people = {};

client.on('connection', function(socket) {

    //join the server
    socket.on('add user', function(user_id) {
        //create user-socket map
        people[user_id] = socket.id;
    });

});
 client side :

     var c = io.connect('http://localhost:3000/', { query: "userId=value01" });



server side :
 // extract userId param from connected url
 io.on('connection', function(socket) {
      var socket_param_userId = socket.handshake['query']['userId'];
      console.log(socket_param_userId);  //show value01
});

您缺少了最重要的部分…您的代码必须验证usr是否是他所说的人。简单明了。我通过多种方式完成了此操作:

如果用户通过PHP代码登录,我会将会话数据移动到mysql数据库中。然后,我会使用PHP端的字符串生成对客户机质询的响应,客户机将质询发送到我的web套接字服务器。WS-server将质询客户机并在mysqldb.Done中查找会话信息

在我最近的开发中,实际的登录过程是通过web套接字服务器完成的。我通过任何DB(在我的实例中是MySQL)验证用户凭据,并将用户名绑定到套接字。完成


不要完全依赖基于javascript的网站来说“我的名字是”。否则,正如你所说,用户模拟就变成了一场闲逛。如果你正在实现一个重要的系统,你必须验证用户就是他所说的那个人。“Web套接字”它们本身并不是为您实现这一点的神奇组件。

我会使用
jsonwebtoken
socketio jwt
模块来解决这个安全问题

服务器:

var secret = 'shhhhhh';
app.get('/getJWT', function(req, res) {
    /* Do your authentication here using header and get the userId */
    var userId = 'someId';
    var jwt = require('jsonwebtoken');
    var token = jwt.sign({ 'userId': userId }, secret);
    res.json({
        token: token
    });
});

var socketioJwt = require('socketio-jwt');
io.use(socketioJwt.authorize({
    secret: secret,
    handshake: true
}));

io.sockets.on('connection', function (socket) {
    var userId = socket.decoded_token.userId;
    /* your logic */
客户:

var token = "token you got from the /getJWT"
var c = io.connect('http://localhost:3000/', { query: "token=" + token });
由于令牌是用密码编码的,客户端无法更改并发送它


参考文章了解为什么这样更好。

Hm,是的,关于people对象,您是对的,它不应该保存在本地。但是关于套接字-用户关联,您说要像socket.join('myuserId')一样加入文件室;我如何从客户端获取
myuserId
?检查“创建Authenicate事件”部分来自我的答案。从客户端发出使用用户名和pwd/token进行身份验证,然后根据get UserID进行身份验证。我如何检查令牌是否有效?我可以看到代码吗?用户是谁?你有用户数据库吗?是的,我有一个用户数据库,我正在使用mongodb。如果客户端将查询更改为:
{query:“userId=另一个用户id”}
??您应该在connect或创建套接字连接时发送数据,并注意您可以发送多个参数。是的,但我的问题是,客户端可以绝对控制他可以发送的内容。例如,他可以说他是其他人。您能告诉我您要在什么上下文中实现此方法吗ke允许您在Express和socket.io之间共享会话,在我看来这是您想要的(备选方案:)。没错!这是我的问题,我无法访问
client.on下用户的会话('connection'…
以查看他在何时/何地登录时的真实身份?如果身份验证成功,您必须想出某种形式的逻辑将变量绑定到登录时的连接上。我有这样一种情况,
请求用户。\u id
但我无法访问它,我不知道该怎么办。