node.js - 通过 Socket.io 连接进行 JWT 授权

标签 node.js authentication socket.io jwt

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

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

这一切都有效,直到它被黑客入侵。但就目前而言,它是王牌。

但是,当涉及到非身份验证服务器的 socket.io 连接时,我们的做法有些鲁莽。我想知道是否有人愿意评估这个过程。 (我很高兴发布更多代码;您告诉我它是否相关)。

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 = {token: 'foo', message: 'bar'},如果有效则接受该 token ,如果无效则返回该 token 。

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

我的问题是:这看起来太简单了;我是否在某些地方偷工减料?你能打败这个脆弱的防御工事吗?

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

提前非常感谢。

最佳答案

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

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

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

  • This article是关于使用 JWT 对 socket.io 通信进行身份验证。这是2014年的,所以可能有点过时,但我认为核心概念仍然有效。

  • 与本文相关的是,有一个专门用于使用 jwt 验证 socket.io 连接的工具。即使您不想使用它,您也可能想探索它的代码以寻找“灵感”。您可以在这里找到它: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
});
  • 一种“单次往返”方法,基本上在握手期间使用查询字符串。其主要缺点是 token 在 URL 中公开,因此可能会被记录或被公开。
  • 关于node.js - 通过 Socket.io 连接进行 JWT 授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34195272/

    相关文章:

    ruby-on-rails - Rails 设计 after_sign_in_path_for(resource) 方法未按预期运行

    google-app-engine - Google App Engine 上的身份验证(网页)

    php - 编辑用户配置文件后更新 Zend_Auth_Storage

    socket.io - 如何禁用socket.io 1.0调试?

    javascript - Nodegit:如何修改文件并推送更改?

    node.js - 在 Express 中生成 _csrf?

    mysql - 服务器 webRTC 连接的好方法

    ios - iOS 中的 Sailsjs 套接字

    javascript - pm2 在同一个端口上运行多个服务器

    node.js - get 的响应数据类型