Socket.io - 为私人消息实现用户套接字关联映射
Socket.io - Implementing a user-socket association map for private messaging
我正在尝试使用 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;
});
});
在我看来,上面代码的问题在于 user_id
是从客户端发送的,因此如果用户以某种方式修改它并发送另一个 user_id
就会发生模拟.
此外,我无法访问 client.on('connection'...
下的 req.user._id
那么我应该如何从服务器端获取 user_id
?我正在使用 node.js、护照和快递。
var people
将可在同一进程上访问。
当您想使用多个套接字服务器进行扩展并在它们之间进行平衡时,这种将人员对象保留在本地的想法将无济于事。
创建 authenticate
事件进行身份验证并设置 socket.userId
和 socket.isAuthenticate = true
标志。在其他事件中,如果 socket.isAuthenticate 为假,则将其踢出。
利用 'socket.io-redis' 适配器在多个 socket.io 服务器之间进行通信。 (因此,当来自服务器 1 的用户 1 向服务器 2 中的用户 2 发送消息时,将起作用)。
对于 socket - 多进程用户关联,你可以使用他们的 userId 加入 Room,在身份验证时,像 socket.join('myuserId');
一样加入房间
以及何时向该用户发送消息,您可以使用 io.to('myuserId').emit('message', "Hi How are you?"):
您可以像这样在套接字连接上发送附加数据:
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 端使用一个字符串来生成对客户端质询的响应,客户端将其发送到我的网络套接字服务器。 WS 服务器将挑战客户端并在 mysqldb 中查找会话信息。完成。
在我最近的开发中,实际的登录过程是通过网络套接字服务器完成的。我通过任何数据库(在我的实例中,MySQL)验证用户凭据并将用户名绑定到套接字。完成...
不要纯粹依靠基于 javascript 的站点来表达 "My name is." 否则,就像您所说的那样,用户冒充就像在公园里散步一样。你必须验证用户是他所说的那个人如果你正在实施一个重要的系统。 "Web sockets" 它们本身并不是为您执行此操作的神奇组件。
我会使用 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 });
由于令牌是用秘密编码的,客户端无法更改和发送它。
参考 this 文章了解为什么这样更好。
我正在尝试使用 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;
});
});
在我看来,上面代码的问题在于 user_id
是从客户端发送的,因此如果用户以某种方式修改它并发送另一个 user_id
就会发生模拟.
此外,我无法访问 client.on('connection'...
下的 req.user._id
那么我应该如何从服务器端获取 user_id
?我正在使用 node.js、护照和快递。
var people
将可在同一进程上访问。
当您想使用多个套接字服务器进行扩展并在它们之间进行平衡时,这种将人员对象保留在本地的想法将无济于事。
创建 authenticate
事件进行身份验证并设置 socket.userId
和 socket.isAuthenticate = true
标志。在其他事件中,如果 socket.isAuthenticate 为假,则将其踢出。
利用 'socket.io-redis' 适配器在多个 socket.io 服务器之间进行通信。 (因此,当来自服务器 1 的用户 1 向服务器 2 中的用户 2 发送消息时,将起作用)。
对于 socket - 多进程用户关联,你可以使用他们的 userId 加入 Room,在身份验证时,像 socket.join('myuserId');
以及何时向该用户发送消息,您可以使用 io.to('myuserId').emit('message', "Hi How are you?"):
您可以像这样在套接字连接上发送附加数据:
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 端使用一个字符串来生成对客户端质询的响应,客户端将其发送到我的网络套接字服务器。 WS 服务器将挑战客户端并在 mysqldb 中查找会话信息。完成。
在我最近的开发中,实际的登录过程是通过网络套接字服务器完成的。我通过任何数据库(在我的实例中,MySQL)验证用户凭据并将用户名绑定到套接字。完成...
不要纯粹依靠基于 javascript 的站点来表达 "My name is." 否则,就像您所说的那样,用户冒充就像在公园里散步一样。你必须验证用户是他所说的那个人如果你正在实施一个重要的系统。 "Web sockets" 它们本身并不是为您执行此操作的神奇组件。
我会使用 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 });
由于令牌是用秘密编码的,客户端无法更改和发送它。
参考 this 文章了解为什么这样更好。