情况
我正在使用库 SocketIO在我的MEAN.JS应用程序。
在 NodeJS 服务器 Controller 中:
var socketio = req.app.get('socketio');
socketio.sockets.emit('article.created.'+req.user._id, data);
在 AngularJS 客户端 Controller 中:
//Creating listener
Socket.on('article.created.'+Authentication.user._id, callback);
//Destroy Listener
$scope.$on('$destroy',function(){
Socket.removeListener('article.created.'+Authentication.user._id, callback);
});
好的。效果很好...
问题
如果一个人(黑客或其他人)获得用户的 ID,他可以在另一个应用程序中在同一 channel 中创建一个监听器,并且可以监视发送给用户的所有数据;例如所有通知...
我怎样才能做同样的事情但更安全?
谢谢!
最佳答案
不久前,我偶然发现了同样的问题。这是我的解决方案(稍作修改 - 用于生产)。
我们将使用 Socket.IO 命名空间
为每个用户创建私有(private)房间。然后我们可以将消息(服务器端)发送到特定的房间。在我们的例子中 - 只有特定的用户才能收到它们。
但是要为每个连接的用户创建私有(private)房间,我们必须首先验证他们的身份。为此,我们将使用简单的身份验证中间件,supported by Socket.IO since its 1.0 release .
1。认证中间件
自 1.0 版本发布以来,Socket.IO supports middleware.我们将用它来:
- 使用 JSON Web Token 验证连接用户身份(参见
jwt-simple
)他向我们发送了查询参数。 (请注意,这只是一个示例,还有许多其他方法可以做到这一点。) - 将他的用户 ID(从 token 中读取)保存在
socket.io
连接实例中,以供以后使用(在第 2 步中)。
服务器端代码示例:
var io = socketio.listen(server); // initialize the listener
io.use(function(socket, next) {
var handshake = socket.request;
var decoded;
try {
decoded = jwt.decode(handshake.query().accessToken, tokenSecret);
} catch (err) {
console.error(err);
next(new Error('Invalid token!'));
}
if (decoded) {
// everything went fine - save userId as property of given connection instance
socket.userId = decoded.userId; // save user id we just got from the token, to be used later
next();
} else {
// invalid token - terminate the connection
next(new Error('Invalid token!'));
}
});
以下示例介绍了如何在客户端初始化连接时提供 token :
socket = io("http://stackoverflow.com/", {
query: 'accessToken=' + accessToken
});
2。命名空间
Socket.io namespaces使我们能够为每个连接的用户创建私有(private)房间。然后我们可以将消息发送到特定的房间(因此只有其中的用户才会收到它们,而不是每个连接的客户端)。
在上一步中,我们确保:
- 只有经过身份验证的用户才能连接到我们的 Socket.IO 接口(interface)。
- 对于每个连接的客户端,我们将用户 ID 保存为
socket.io
连接实例 (socket.userId
) 的属性。
剩下要做的就是在每次连接时加入正确的房间,名称等于新连接的客户端的用户 ID。
io.on('connection', function(socket){
socket.join(socket.userId); // "userId" saved during authentication
// ...
});
现在,我们可以发出只有该用户才会收到的有针对性的消息:
io.in(req.user._id).emit('article.created', data); // we can safely drop req.user._id from event name itself
关于angularjs - MEANJS:SocketIO 中的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31243164/