728x90

- Middleware란?

라우트 핸들러가 실행되기 전에 실행된다. Request와 Response 객체에 접근 할 수 있다.

  • 자유롭게 코드 실행
  • 요청과 응답 객체를 변경
  • 요청 응답 사이클 중단
  • 다음 미들웨어 실행

- 미들웨어 선언법

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request ...');
    next();
  }
}

- 미들웨어 적용법 (app.module.ts)

- 간단

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('cats');
  }
}

 

- 세부적

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
      .forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });

ab 아무거 cd, 그냥 *은 모든

 

- 제외

 consumer
      .apply(LoggerMiddleware)
      .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.POST },
        'cats/(.*)',
      )
      .forRoutes(CatsController);

 

forRoutes => 어떤 라우트에 적용할 지

'cats/(.*)' => 이렇게 string으로도 가능

 

- 순차적 = 여러개

    consumer.apply(cors(), helmet(), logger()).forRoutes(CatsController);

 

- 글로벌 적용 (main.ts)

const app = await NestFactory.create(AppModule);
app.use(Logger);
await app.listen(3000);

- codefactory 강의에서 작성한  Bearer 토큰 검증 예시

실제로 뒤에 guard에서 검증하면 될 것이기 때문에 사실 아래 코드는 그냥 사용 예시로 보는게 좋을 듯.

jwtService의 경우 authModule에서 jwtModule exports 필요

import {
  BadRequestException,
  Injectable,
  NestMiddleware,
  UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { NextFunction, Request, Response } from 'express';
import { envKeys } from 'src/common/const/env.const';

@Injectable()
export class BearerTokenMiddleware implements NestMiddleware {
  constructor(
    private readonly jwtService: JwtService,
    private readonly configService: ConfigService,
  ) {}
  async use(req: Request, res: Response, next: NextFunction) {
    const authHeader = req.headers.authorization;

    if (!authHeader) return next();

    const token = this.validateBeaerToken(authHeader);

    try {
      const decodedPayload = this.jwtService.decode(token);

      if (decodedPayload.type !== 'refresh' && decodedPayload.type !== 'access')
        throw new UnauthorizedException('잘못된 토큰입니다!');

      const secretKey =
        decodedPayload.type === 'refresh'
          ? envKeys.refreshTokenSecret
          : envKeys.accessTokenSecret;

      const payload = await this.jwtService.verifyAsync(token, {
        secret: this.configService.get<string>(secretKey),
      });

      req.user = payload;
      next();
    } catch (e) {
      if (e.name === 'TokenExpiredError')
        throw new UnauthorizedException('토큰이 만료됐습니다.');
      next();
    }
  }

  validateBeaerToken(rawToken: string) {
    const basicSplit = rawToken.split(' ');

    if (basicSplit.length !== 2)
      throw new BadRequestException('토큰 포맷이 잘못됐습니다!');

    const [bearer, token] = basicSplit;

    if (bearer.toLowerCase() !== 'bearer')
      throw new BadRequestException('토큰 포맷이 잘못됐습니다!');
    return token;
  }
}
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(BearerTokenMiddleware)
      .exclude(
        {
          path: 'auth/login',
          method: RequestMethod.POST,
        },
        { path: 'auth/register', method: RequestMethod.POST },
      )
      .forRoutes('*');
  }
}

 

 

https://fastcampus.co.kr/classroom/239666

 

커리어 성장을 위한 최고의 실무교육 아카데미 | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

fastcampus.co.kr

 

728x90

'코딩 > Nest.js' 카테고리의 다른 글

RBAC (Role Based Access Control)  (0) 2024.10.23
Guard 실사용적  (0) 2024.10.23
passport  (0) 2024.10.22
JWT  (0) 2024.10.22
Mapped Type  (0) 2024.10.22

+ Recent posts