使用 jwt 对 Web 套接字连接进行身份验证是否安全?

时间:2021-02-04 11:13:28

标签: javascript socket.io jwt

如果客户端 javascript 可以访问 JWT 加密,它们是否安全? 如果没有,我如何使用它们来验证我的网络套接字连接?

1 个答案:

答案 0 :(得分:1)

tl;dr - 是的,可以将 JWT 用于 Web 套接字连接,如果牢记某些规定


让我们先总结一下什么是 JSON 网络令牌 (JWT)。 JWT 由三部分构成:标题有效载荷签名

  • Header 包含令牌的类型和签名算法,即 HS256 或 RSA。 HeaderBase64Url 编码的。

  • Payload 包含声明,还可以包含自定义数据,例如来自数据库的用户 ID。 Payload 也是 Base64Url 编码的。

  • 签名(令牌的最后一部分)是通过对标题有效载荷和一个Secret 只有您知道,使用指定的算法。

因此,知道这一点,我们可以说令牌的内容(标头和有效负载)不安全,因此不应包含敏感数据。但是,令牌使用只有您知道(您的服务器)知道的 secret 签名这一事实使其对于其用途而言非常安全。因为即使从客户端使用令牌,也只有您可以发出这些令牌,并且只有您可以创建有效的令牌。不能简单地伪造可以在您的 api 中使用的令牌。仍然有人可以在客户端窃取令牌,但保持令牌的较短到期时间对您有利。


使用 JWT 验证 websocket 连接

只要您不使用长期存在的令牌,甚至不使用无限有效的令牌(到期时间),我就会说这是一个可靠的解决方案。通常 JWT 用于 REST API 环境,因此用户首先使用身份验证端点(例如用户名和密码)进行授权,然后分发有效的 JWT。

我建议同样建立网络套接字连接(在你的情况下是 socket.io)。像这样(当然这取决于您的后端情况):

// client

const axios = require('axios');
const io = require('socket.io-client');

const { token } = await axios.post('/auth/login', credentials);

const socket = io("ws://example.com/", {
  auth: {
    token: "123"
  }
});
// server
// socket.io middleware

io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  // ... check token or whatever
});