通过 Socket.io 连接的 JWT 授权

JWT Authorization Over Socket.io Connection

事实上我还没有找到这个问题的现有答案,这让我觉得我问错了问题。如有必要,请随时(轻轻地或以其他方式)将我推向更好的道路。

我们使用专用的身份验证服务器,其目的是 (1) 给定登录凭据,return 具有近期 exp 的 JWT 或 (2) 给定 JWT,根据一套规则,发出一个新的 JWT。本质上是刷新。

在被黑之前,这一切都很好。但现在,它是王牌。

但是,当涉及到 socket.io 与非授权服务器的连接时,我们的想法有点仓促。我想知道是否有人愿意评估这个过程。 (我很高兴 post 更多代码;你告诉我它是否相关)。

1) 初始 socket.io 连接导致质询:

this.socket.emit('authenticate'); // the challenge

this.authTimeout = setTimeout(() => {
  this.socket.disconnect('unauthorized', errors);
}, TIME_TO_AUTHENTICATE); // the response kills this!

this.socket.on('authenticate', token => {
  clearTimeout(this.authTimeout);
  this._authenticate(token)
})

2) 后续消息必须包含以下格式的 "payload" 消息: payload = {token: 'foo', message: 'bar'},如果有效则接受哪个令牌,如果无效则 returned。

此外,资源服务器发送自己的周期性heartbeat,必须由heartbeat {token}确认。

我的问题是:这似乎太简单了;我在某处偷工减料吗?你能打败这脆弱的防御工事吗?

明确地说,我们希望在这里推出我们自己的模块。我很高兴看到任何现有的东西;只是还没有找到任何我可以开始说服老板完全满足我们需求的东西。

非常感谢。

我无法完全分析该方法或确保它没有缺陷,但我想指出一些我想到的事情:

  • 除了在身份验证质询超时的情况下断开用户连接外,您必须确保服务器在授权质询完成之前不会向该用户发送任何非 public 消息实际履行成功。否则,在超时之前有一段时间,用户可以在未经过身份验证的情况下接收消息。

  • 我假设如果令牌无效(或以某种方式阻止发送非public消息),您也会断开套接字。

  • This article 是关于使用 JWT 验证 socket.io 通信。它是从 2014 年开始的,所以它可能有点过时了,但我认为核心概念仍然有效。

  • 与本文相关,有一个工具专门用于使用 jwt 验证 socket.io 连接。即使您不想使用它,您也可能想要探索其代码以查找 "inspiration"。您可以在这里找到它:socketio-jwt

您可以看到该工具能够使用两种不同的方法:

  1. 一种与您的方法非常相似的方法:

来自 socketio-jwt/blob/master/lib/index.js

if(options.required){
  var auth_timeout = setTimeout(function () {
    socket.disconnect('unauthorized');
  }, options.timeout || 5000);
}

socket.on('authenticate', function (data) {
  // ...
  // Token validation

  // Emit "authenticated" event if token is valid, the server can use
  // this event as a point to send messages, once token is valid
});
  1. 一种 "One roundtrip" 方法,基本上在握手期间使用查询字符串。其主要缺点是令牌在 URL 中公开,因此它可能会被记录或被公开。