Socket.io 身份验证的最佳方法是什么?

问题描述 投票:0回答:2

我的 NodeJS 服务器正在提供 API 和 socket.io 连接。服务器根据登录时生成的 JWT 访问令牌和刷新令牌对 API 进行身份验证。该应用程序正在为管理仪表板提供 API。只有一种类型的用户,每个用户对所有内容都有平等的访问权限。我唯一想确认的是尝试连接到服务器的套接字客户端是我的客户端应用程序中的用户。

  • 验证我的 socket.io 连接的最佳且简单的方法是什么?
  • 服务器和客户端应用程序之间共享的固定 API 密钥是否适合此目的,或者是否有其他简单的方法来实现此目的?
node.js authentication socket.io
2个回答
1
投票

我们可以将 JWT 令牌作为来自前端的连接请求的查询参数传递。我们可以在连接握手期间验证服务器中的 JWT 令牌,并且可以接受或拒绝请求。客户端代码看起来像这样

var socket = io.connect('http://localhost:3000',{ query: "token=abcd" });

其中

abcd
是您作为查询参数传递的令牌。

服务器端代码看起来像这样

io.on('connection', function (socket) {
    const token = socket.handshake.query['token'];
    // Your JWT authentication code goes here.
});  

其中

token
保存着客户端发送的令牌。我建议采用这种身份验证机制作为

  1. 身份验证发生在连接时,因此可以在初始级别完成拒绝和接受。
  2. 每次重新连接也会验证请求。
  3. 单次连接不会出现重复验证,从而降低了验证时间。
  4. 在中间更改 JWT 令牌将导致关闭现有连接并使用新令牌重新连接,因此发生任何攻击的可能性非常小。

0
投票

@sachin 的答案是一个很好的模式,但没有遵循 socket.io 的建议,即使用他们的“auth”处理程序。

https://socket.io/docs/v4/client-options/#auth

https://socket.io/docs/v4/middlewares/#sending-credentials

我针对您的情况提出以下建议:

(client-side)
import { io } from "socket.io-client";

const jwt = await yourAuthLogic();

const socket = io({ auth: { token: jwt } });

// any refresh on client JWT token
refreshedToken()
  .then((newjwt) => {
    socket.auth.token = newjwt;
    socket.disconnect().connect();
  });

// in case of unauthorized
socket.on("connect_error", (err) => {
  if (err && err.message === "unauthorized") handleUnauthorized();
});
(server-side)

io.use((socket, next) => {
  const jwt= socket.handshake.auth.token;
  const isValid = validateJWT(jwt);
  if (isValid) next();
  else {
    const err = new Error("unauthorized");
    err.data = { content: "Please retry later" }; // additional details
    next(err);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.