通过 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。
您可以看到该工具能够使用两种不同的方法:
- 一种与您的方法非常相似的方法:
来自 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
});
- 一种 "One roundtrip" 方法,基本上在握手期间使用查询字符串。其主要缺点是令牌在 URL 中公开,因此它可能会被记录或被公开。
事实上我还没有找到这个问题的现有答案,这让我觉得我问错了问题。如有必要,请随时(轻轻地或以其他方式)将我推向更好的道路。
我们使用专用的身份验证服务器,其目的是 (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。
您可以看到该工具能够使用两种不同的方法:
- 一种与您的方法非常相似的方法:
来自 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
});
- 一种 "One roundtrip" 方法,基本上在握手期间使用查询字符串。其主要缺点是令牌在 URL 中公开,因此它可能会被记录或被公开。