【问题标题】:NestJS WebSocket Gateway - how get full path for initial connection?NestJS WebSocket 网关 - 如何获得初始连接的完整路径?
【发布时间】:2023-01-09 06:39:17
【问题描述】:

我正在向我们的 NestJS 应用程序添加一个 socket.io“聊天”实现,目前提供一系列 HTTP REST API。我们有相当复杂的基于租户的身份验证,为我们的 REST API 使用守卫。用户可以属于一个或多个租户,他们通过 API URL 定位给定租户,API URL 可以是子域或基于路径,具体取决于部署环境,例如:

//Subdomain based
https://tenant1.api.server.com/endpoint
https://tenant2.api.server.com/endpoint
//Path based
https://api.server.com/tenant1/endpoint
https://api.server.com/tenant2/endpoint

这一切都适用于 REST API,允许我们在守卫中确定预期的租户(并验证用户对该租户的访问权限)。

新的 socket.io 实现在端点“/socket”的同一端口上公开,这意味着可能的完整连接路径可能是:

https://tenant1.api.server.com/socket
https://api.server.com/tenant1/socket

理想情况下,我想在 websocket 连接期间验证用户(通过 JWT)和对组的访问(如果未通过验证,它们会立即断开连接)。我一直在努力用守卫来实现,所以我在套接字网关中完成了 JWT/用户验证,它工作正常。对于租户验证,如上所述,我需要用于连接的完整 URL,因为我将查看子域或路径,具体取决于部署。我可以从客户端握手标头中获取主机,但找不到任何方法来获取路径。有没有办法从握手或 Nest 中获取完整路径?我认为在实现 OnGatewayConnection 时,我在 handleConnection 方法中访问的内容可能受到限制。

到目前为止的代码:

@WebSocketGateway({
  namespace: 'socket',
  cors: {
    origin: '*',
  },
})
export class ChannelsGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {

  @WebSocketServer() public server: Server

  //Init using separate socket service (allowing for other components to push messages)
  afterInit(server: Server) {
    this.socketService.socket = server
    Logger.debug('Socket.io initialized')
  }

  //Method for handling the client initial connection
  async handleConnection(client: Socket, ...args: any[]) {
    //This line gets me the host, such as tenant1.api.server.com but without the path
    const host = client.handshake.headers.host

    //Get bearer token from authorizaton header and validate
    //Disconnect and return if not validated
    const bearerJwt = client.handshake.headers.authorization
    const decodedToken = await validateJwt(bearerJwt).catch(error => {
      client.disconnect()
    })
    if (!decodedToken) {
      return
    }

    //What can I use to get at the path, such as:
    //api.server.com/tenant1/socket
    //tenant1.api.server.com/socket
    
    //Then I can extract the "tenant1" with existing code and validate access
    //Else disconnect the client


    //Further code to establish a private room for the user, etc...
  }

  //other methods for receiving messages, etc...
}

【问题讨论】:

  • 您找到解决方案了吗?如果你这样做了,你可以添加你自己的答案并接受它。

标签: node.js sockets websocket socket.io nestjs


【解决方案1】:

要访问端点的 URL 参数,您可以使用握手作为套接字连接处理函数中的参数提供的对象。

握手对象包含有关套接字连接的信息,包括 URL 参数

例如,如果端点 URL 是 ws://localhost:3000/chat?userId=123,您可以像这样访问 userId 参数的值:

@WebSocketGateway()
export class MySocketController implements OnGatewayConnection {

  async handleConnection(client: any) {
    const userId = client.handshake.query.userId;
    console.log(userId);
  }
}

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 2010-11-28
    相关资源
    最近更新 更多