websocket 如何使用中间件为nestjs项目中socket-io验证jwt令牌?

nx7onnlm  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(201)

我有一个nestjs项目,我在其中使用socket-io。我的中间件(socketJwtMiddleware)有一个问题,它没有抛出错误,但不工作。我声明了一个socketjwtMiddleware,它验证jwt令牌,实际上当socket连接时,中间件不执行

import {
  Injectable,
  NestMiddleware,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Request, Response, NextFunction } from 'express';
import { Socket } from 'socket.io';

@Injectable()
export class SocketJwtMiddleware implements NestMiddleware {
  constructor(private readonly jwtService: JwtService) {}
  use(socket:Socket, next: NextFunction) {
    console.log('+++++++++++++++++');

    const token = socket.handshake.auth?.token;
    try {
      if (token) {
        const decode = this.jwtService.verify(token, {
          secret: process.env.JWT_SECRET,
        });
        socket['user'] = decode;
      }
      console.log('Request...');
    } catch (error) {
      return next(new UnauthorizedException());
    }

    next();
  }
}

我的套接字网关是

import {
  MiddlewareConsumer,
  NestModule,
  OnModuleInit,
  UseGuards,
} from '@nestjs/common';
import {
  ConnectedSocket,
  MessageBody,
  OnGatewayConnection,
  OnGatewayDisconnect,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { SocketJwtMiddleware } from './socketJwt.middleware';

@WebSocketGateway({
  cors: {
    path: '*',
    method: ['GET', 'POST'],
  },
})
export class SocketGateway implements OnModuleInit {
  @WebSocketServer()
  server: Server;

  onModuleInit() {
    this.server.on('connection', (socket: any) => {
      console.log('connection', socket.id);
    });
  }

  @SubscribeMessage('message')
  handleEvent(
    @MessageBody() data: string,
    @ConnectedSocket() client: Socket,
  ): string {
    console.log('message', data);
    console.log(client.id);

    return data;
  }
}

socketModule是

import {
  MiddlewareConsumer,
  Module,
  NestMiddleware,
  NestModule,
} from '@nestjs/common';
import { SocketJwtMiddleware } from './socketJwt.middleware';
import { SocketGateway } from './socket.gateway';

@Module({
  providers: [SocketGateway],
})
export class SocketModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(SocketJwtMiddleware).forRoutes("");
  }
}

我的套接字连接上了,但是我的中间件不工作,请帮助我

vzgqcmou

vzgqcmou1#

看起来您正在尝试使用SocketJwtMiddleware作为NestJS项目中套接字连接的中间件。但是,当在SocketModule中配置中间件时,您将缺少中间件应该应用到的路由的适当配置。
要解决这个问题,您需要在consumer.apply()函数调用的forRoutes方法中指定中间件应该应用到的路由。下面是更新的代码:

import {
  MiddlewareConsumer,
  Module,
  NestMiddleware,
} from '@nestjs/common';
import { SocketJwtMiddleware } from './socketJwt.middleware';
import { SocketGateway } from './socket.gateway';

@Module({
  providers: [SocketGateway],
})
export class SocketModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(SocketJwtMiddleware)
      .forRoutes(SocketGateway); // Specify the routes here, e.g., SocketGateway class

    // If you want to apply the middleware to multiple routes, you can pass an array of routes
    // consumer.apply(SocketJwtMiddleware).forRoutes(SocketGateway, AnotherSocketGateway);
  }
}

请确保将SocketGateway替换为表示套接字路由的适当类。通过这样做,中间件应该被正确地应用,并且SocketJwtMiddleware的使用方法应该被触发用于传入的套接字连接。

相关问题