@Aslero

Почему возникает ошибка у JwtWSGuard nestjs + websoket?

привет делаю гварда для Websocket, почему ругается?

auth.module.ts
import { Module } from '@nestjs/common';
import { AuthController } from './v1/auth.controller';
import { AuthService } from './v1/auth.service';
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtStrategy } from './strategies/jwt.strategy';
import { CqrsModule } from '@nestjs/cqrs';

@Module({
  imports: [
    ConfigModule,
    JwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        secret: configService.get('jwt.token.secret'),
        signOptions: {
          expiresIn: configService.get('jwt.token.expiresIn'),
        },
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [],
  providers: [
    JwtStrategy,
  ],
})
export class AuthModule {}


chat.geteway

@UseGuards(JwtWsAuthGuard)
@WebSocketGateway({
  namespace: 'chat',
  cors: {
    origin: '*',
    credentials: true,
  },
})
export class RoomGateway {


и сам JwtWsAuthGuard
TypeError: Cannot read properties of undefined (reading 'verifyAsync')

import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { JwtService } from '@nestjs/jwt';
import { WsException } from '@nestjs/websockets';

@Injectable()
export class JwtWsAuthGuard extends AuthGuard('jwt-ws') {
  constructor(private readonly jwtService: JwtService) {
    super();
  }

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const client = context.switchToWs().getClient();
    const token = this.getTokenFromWebSocket(client);

    if (!token) {
      throw new WsException('Unauthorized');
    }

    const user = await this.validateToken(token);

    if (!user) {
      throw new WsException('Unauthorized');
    }
    client.user = user;

    return true;
  }

  private getTokenFromWebSocket(client: any): string | null {
    return this.getCookieValue(
      client.handshake?.headers.cookie,
      '_Secure-access-token',
    );
  }

  private async validateToken(token: string): Promise<any> {
    try {
      const jwtPayload: any = await this.jwtService.verifyAsync(token, {
        secret: 'secretKey',
      });
      return jwtPayload;
    } catch (error) {
      console.log(error);
      return null;
    }
  }
}
  • Вопрос задан
  • 266 просмотров
Решения вопроса 1
@Aslero Автор вопроса
Чутка переделал все

import { ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

export class WsAuthGuard extends AuthGuard('wsjwt') {
  constructor() {
    super();
  }

  getRequest(context: ExecutionContext) {
    return context.switchToWs().getClient().handshake;
  }
}


import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class WsJwtStrategy extends PassportStrategy(Strategy, 'wsjwt') {
  constructor(private readonly configService: ConfigService) {
    super({
      ignoreExpiration: false,
      secretOrKey: configService.get('jwt.token.secret'),
      jwtFromRequest: ExtractJwt.fromExtractors([
        (request: Request) => {
          const token = this.getTokenFromWebSocket(request.headers?.cookie);
          return token;
        },
      ]),
    });
  }

  private getTokenFromWebSocket(cookie: string): string | null {
    return this.getCookieValue(cookie, '_Secure-access-token');
  }

  private getCookieValue(cookieString: string, cookieName: string) {
    const cookies = cookieString.split('; ');
    for (const cookie of cookies) {
      const [name, value] = cookie.split('=');
      if (name === cookieName) {
        return value;
      }
    }
    return null;
  }

  async validate(payload: any) {
    if (!payload) new UnauthorizedException();

    return {
      userId: payload.sub,
      phone: payload.phone,
      email: payload.email,
      type: payload.type,
    };
  }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы