[2024.07.25 TIL] 내일배움캠프 71일차 (최종 팀프로젝트, 로그인/회원가입/로그아웃/토큰재발급 구현)

My_Code·2024년 7월 25일
0

TIL

목록 보기
86/113
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ RefreshToken 검증을 기존의 PassportStrategy 활용하기

  • 원래는 Refresh Token을 검증하는 과정을 미들웨어를 사용함

  • 그러다 보니 검증하는 코드까지 전부 구현했음

  • 생각해보니 JwtStrategy를 이용해서 AccessToken 유효성 검사가 굉장히 간단하게 이루어 졌음

  • 그래서 RefreshToken 검증을 기존의 PassportStrategy 활용해서 검증하는 방법을 찾아봄

  • 처음에는 npm install passport-custom 이라는 라이브러리를 사용했지만 아에 동작하지 않았기에 다른 방법을 찾음

  • 또 달리 찾은 방법 자체는 생각보다 간단했음

  • 단순하게 Strategy의 별명을 통해서 사용이 가능함

@Injectable()
export class RefreshTokenStrategy extends PassportStrategy(Strategy, 'refreshToken') {
  constructor(
    private readonly configService: ConfigService,
    @InjectRepository(User) private readonly usersRepository: Repository<User>
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: configService.get('REFRESH_SECRET_KEY'),
    });
  }

  async validate(payload: any) {
    const user = await this.usersRepository.findOne({
      where: { id: payload.id },
    });

    if (!user) {
      throw new NotFoundException('일치하는 사용자가 없습니다.');
    }

    return user;
  }
}
  • 그리고 컨트롤러에서는 다음과 같이 사용하면 됨
/**
   * 로그아웃
   * @param req
   * @returns
   */
  @ApiBearerAuth()
  @UseGuards(AuthGuard('refreshToken'))
  @Post('/sign-out')
  async signOut(@Req() req: any) {
    return await this.authService.signOut(req.user.id);
  }

✏️ 하나의 DTO에서 여러 엔티티 상속 받아서 사용하기

  • 같은 팀원분께서 질문주신 내용이 처음 접하는 DTO 형식이기에 내용을 정리함

  • 하나의 DTO에서 공연과 스케줄 엔티티에서 각각 필요한 컬럼이 존재했음

  • 기존에는 하나의 엔티티에서 필요한 컬럼을 가져올 때 PickType()을 사용해서 가져왔음

  • 하지만 두 가지 엔티티에서 필요한 값을 가져오는 경우는 이번이 처음이라서 방법을 검색함

  • 해결 방법은 IntersectionType()를 사용해서 여러 개의 타입을 모두 상속 받아 사용할 수 있음

  • https://github.com/nestjs/graphql/issues/2726

class A extends IntersectType(
  PickType(B, ['field1', 'field2']),
  PickType(PartialType(B), ['field3', 'field4'])
) {}
  • 하지만 공연을 수정하기 위한 DTO이기 때문에 반드시 입력될 필요가 없음

  • PickType()을 쓰면 반드시 입력되어야 함

  • 그래서 PartialType()을 이용해서 Optional하게 입력되도록 만들어야 한다는 것은 찾음

  • 참고 : https://velog.io/@yullivan/NestJS-Mapped-Types와-혼란

  • 결과적으로는 내가 원하는 코드를 공식문서와 구글링으로 찾지 못해서 뤼튼을 통해 원하는 코드를 찾음 (튜터님이 계시지 않아서 최후의 수단으로 사용)

// Show 엔티티에서 필요한 컬럼 선택
class ShowDto extends PickType(Show, ['title', 'description'] as const) {}

// Schedule 엔티티에서 필요한 컬럼 선택
class ScheduleDto extends PickType(Schedule, ['date', 'time'] as const) {
  // Schedule 관련 데이터가 배열 형태로 입력될 수 있도록 설정
}

// UpdateShowDto 정의
export class UpdateShowDto extends IntersectionType(
  PartialType(ShowDto),
  PartialType(ScheduleDto)
) {
  schedules?: ScheduleDto[]; // ScheduleDto 배열 형태로 입력
}


📌 Tomorrow's Goal

✏️ 역할(Role) 가드 구현

  • 내일은 로그인한 사용자의 역할에 따라 해당 작업이 가능한지, 불가능한지 검증하는 가드를 구현할 예정

  • 여기서는 USER와 ADMIN으로 구분해서 공연 관련 작성, 수정, 삭제는 ADMIN만 작업이 가능하도록 만들 예정


✏️ 이미지 업로드 기능 구현

  • 예전에 사용하던 이미지 업로드 코드를 기반으로 이번 프로젝트에 알맞은 형태로 바꿀 예정

  • 공연 등록, 수정에만 사용되는게 아니라 사용자 프로필 이미지 업로드에도 사용되어야 함

  • 그렇기에 사용자 프로필에서는 한 장만 업로드되어야 하고 공연 등록, 수정에는 여러 장의 이미지가 업로드 가능하도록 구현해야 함



📌 Today's Goal I Done

✔️ 인증, 인가 API 구현

  • 오늘은 로그인/회원가입/로그아웃/토큰 재발급 관련 API를 구현함

  • 로그인과 회원가입은 매번 구현하던 내용이기에 금방 끝남

  • 하지만 이번에 구현하는 로그아웃과 토큰 재발급에서 사용할 Refresh Token 검증 과정에 대해서 다르게 구현함

  • 원래는 미들웨어였지만 PassportStrategy를 이용해서 조금 더 간결하게 구현함

  • 그리고 다른 팀원분께서 하나의 DTO에서 여러 개의 엔티티의 데이터를 상속 받아서 사용하는 방법에 대해서 물어보셔서 함께 이를 해결함


profile
조금씩 정리하자!!!

0개의 댓글