angularjs - MEANJS:SocketIO 中的安全性

标签 angularjs node.js security socket.io meanjs

情况

我正在使用库 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.我们将用它来:

  1. 使用 JSON Web Token 验证连接用户身份(参见 jwt-simple )他向我们发送了查询参数。 (请注意,这只是一个示例,还有许多其他方法可以做到这一点。)
  2. 将他的用户 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)房间。然后我们可以将消息发送到特定的房间(因此只有其中的用户才会收到它们,而不是每个连接的客户端)。

在上一步中,我们确保:

  1. 只有经过身份验证的用户才能连接到我们的 Socket.IO 接口(interface)。
  2. 对于每个连接的客户端,我们将用户 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/

相关文章:

javascript - Angular - 添加选项以使用 Jquery 进行选择

javascript - ionic - angularjs - 在 Android 设备上重新打开应用程序后列表不呈现

angularjs - 通过模板传递值

javascript - Spotify 网络 API 结果 "undefined"

javascript - 有没有办法在没有 mongodb 的情况下创建像 _id 字符串一样的 mongodb?

php - 如何防止 PHP 中的 SQL 注入(inject)?

php - 如何在 laravel 的 cookie 上设置安全标志

javascript - 带有闭包编译器和/或闭包库的 html5、angularJS

node.js - 无法在 ubuntu 中启动 Node 服务器

.net - 防止来自恶意 protobuf 数据包的 DoS 攻击