NestJS - Как создать службу упаковки поверх службы jwt (из модуля jwt)

Извините за плохой английский, я из Украины:) Не могли бы вы рассказать мне, как я могу создать свой собственный сервис, который расширяет Jwt-сервис, предоставляемый модулем jwt из пакета npm? Я хочу создать свой собственный JwtService для обнаружения ошибок и изолирования повторяющейся логики для создания и проверки токенов. Пожалуйста, помогите мне, как я могу это сделать. Примеры кода прилагаются.

import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtVerifyOptions } from '@nestjs/jwt';

@Injectable()
export class OwnJwtService extends NestJwtService {
  constructor() {
    super({});
  }

  async verifyAsync<T>(token: string, options?: JwtVerifyOptions): Promise<T> {
    try {
      const res = await super.verifyAsync(token, options);
      console.log('res', res);
      return res;
    } catch (error) {
      // My own logic here ...
      throw new BadRequestException({
        error,
        message: 'Error with verify provided token',
      });
    }
  }
}

или, может быть, мне нужно внедрить службу jwt nestjs в мою собственную службу? пример:

import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtVerifyOptions } from '@nestjs/jwt';

@Injectable()
export class OwnJwtService {
  constructor(private readonly jwtService: NestJwtService) {}

  async verifyAsync<T>(token: string, options?: JwtVerifyOptions): Promise<T> {
    try {
      const res = await this.jwtService.verifyAsync(token, options);
      console.log('res', res);
      return res;
    } catch (error) {
      throw new BadRequestException({
        error,
        message: 'Error with verify provided token',
      });
    }
  }
}

а также

import { JwtModule as NestJwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Module } from '@nestjs/common';

import { OwnJwtService } from 'src/modules/jwt/jwt.service';

@Module({
  imports: [
    NestJwtModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        signOptions: {
          expiresIn: process.env.JWT_EXPIRES_IN,
        },
        secret: process.env.JWT_SECRET,
        secretOrPrivateKey: process.env.JWT_SECRET,
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [OwnJwtService],
  exports: [OwnJwtService],
})
export class JwtModule {}

но у меня это не работает, и у меня похожие ошибки:

Ошибка: Nest не может разрешить зависимости OwnJwtService (?). Убедитесь, что аргумент JwtService с индексом [0] доступен в контексте AuthModule.

0 ответов

Во-первых, обратите внимание, что JwtModule в основном создает модуль на основе jsonwebtoken и ваши пользовательские ошибки не предназначены для обработки внутри него.

Во-вторых, когда вы используете registerAsync, вы должны получать переменные ENV с помощью ConfigService, как в configService.get('JWT_SECRET').

В-третьих, ваш вопрос неэффективен. JwtModule уже делает все, что вам нужно. Вам просто нужно это реализовать. Опять же, просто подумайте об этом как о jsonwebtokenпакет адаптирован для Nest. Вот и все.

При регистрации вам нужно войти в систему и обновить токен (если есть). signкогда вы создаете новый токен. И в ваших запросах промежуточное ПО вы verify.

Одна из серьезных проблем с Nest - это его документация. В нем нет всего, что вам нужно. Может быть более одного способа проверить маршрут, но самый простой - просто использовать промежуточное ПО Express, как в типичном приложении Express.

Для этого нужно реализовать это в AppModule вот так:

@Module(...)
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
    consumer.apply(cookieParser(), AuthMiddleware).forRoutes('/');
  }
}

В этом примере я также регистрирую модуль cookieParser()потому что я отправляю токены в куки. Подойдут и другие модули cookie. И NestModule, и MiddlewareConsumer происходят из @nestjs/common.

AuthMiddleware - это промежуточное ПО, которое я сделал с помощью этого скелета...

export class AuthMiddleware implements NestMiddleware {
  constructor(
    private readonly configService: ConfigService,
    private readonly jwtService: JwtService
  ) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const { yourJwtToken } = req.cookies;
    const isValidToken = this.jwtService.verify(
      yourJwtToken,
      this.configService.get('JWT_SECRET'),
    );

    if (!isValidToken) throw new UnauthorizedException();

    // etc...

    next();
  }
}

Наконец, вы можете попросить применить AuthGuard.

Если вы используете паспортные, вам нужно просто следовать документации, чтобы применить их. Они уже выкидывают ошибки, если вы. Если вы хотите его изменить, просто перепишите его методы.

Вы также можете сделать это вручную. Просто используйте консоль, чтобы создать охранника, и там вы можете проверить аутентификацию context.switchToHttp().getRequest() и верните логическое значение после проверки учетных данных и используйте конструктор для проверки разрешений, если хотите.

Вы также можете пропустить конфигурацию промежуточного программного обеспечения сверху и реализовать логику внутри защиты, если хотите.

Опять же, я не думаю, что изменение JwtModule - лучшая идея.

Другие вопросы по тегам