Skip to content

[재하] 1123(목) 개발기록

박재하 edited this page Nov 24, 2023 · 6 revisions

체크리스트

  • 트러블 슈팅 : Object Storage 에러 => 해결
  • AWS-SDK를 이용한 NCP Object Storage 파일 업로드, 다운로드

트러블 슈팅 : Object Storage 에러 => 해결

S3 Endpoint 주소 문제

NCloud 공식문서에 나와있는 S3 Endpoint 주소가 문제였다..

스크린샷 2023-11-23 오후 12 42 10

여기 나와있는 주소를 썼는데 ACCESS KEY가 없다고 나와 뭔가 잘못한 줄 알고 한참을 헤맸는데

스크린샷 2023-11-23 오후 12 42 49

혹시나 싶어 다른 문서에 나와있는

스크린샷 2023-11-23 오후 12 42 54

이 주소를 보니까 다른거야.. 그래서 이걸로 했더니 됨. ㅋ

알고보니 내가 보던 공식문서는 financial용 ncloud로 서버도 인증키도 따로 관리되는 거였다... 내가 바보 ㅇㅈ

업로드 로직 추가

이제 주석처리해 두었던 업로드 로직을 다시 추가해줬다.

async createBoard(
  createBoardDto: CreateBoardDto,
  userData: UserDataDto,
  files: Express.Multer.File[],
): Promise<Board> {
  const { title, content } = createBoardDto;

  const user = await this.userRepository.findOneBy({ id: userData.userId });

  const images: Image[] = [];
  for (const file of files) {
    const image = await this.uploadFile(file);
    images.push(image);
  }

  const board = this.boardRepository.create({
    title,
    content: encryptAes(content), // AES 암호화하여 저장
    user,
    images,
  });
  const createdBoard: Board = await this.boardRepository.save(board);

  createdBoard.user.password = undefined; // password 제거하여 반환
  return createdBoard;
}

파일 목록에서 순서대로 읽어와 uploadFile() 호출

async uploadFile(file: Express.Multer.File): Promise<Image> {
  if (!file.mimetype.includes('image')) {
    throw new BadRequestException('Only image files are allowed');
  }

  const { mimetype, buffer, size } = file;

  const filename = uuid();

  // NCP Object Storage 업로드
  AWS.config.update(awsConfig);
  const result = await new AWS.S3()
    .putObject({
      Bucket: bucketName,
      Key: filename,
      Body: buffer,
      ACL: 'public-read',
    })
    .promise();
  Logger.log('uploadFile result:', result);

  const updatedImage = await this.imageRepository.save({
    mimetype,
    filename,
    size,
  });

  return updatedImage;
}

업로드 파일 로직은 uuid로 생성된 식별자를 파일이름으로 Object Storage에 업로드하고, 나머지 파일에 대한 정보는 관계형 DB 이미지 테이블에 저장한다.

다운로드 로직 추가

yarn workspace server add form-data

폼데이터로 응답을 해야하기 때문에 form-data 모듈을 설치해줬다.

async downloadFile(filename: string): Promise<Buffer> {
  // NCP Object Storage 다운로드
  AWS.config.update(awsConfig);
  const result = await new AWS.S3()
    .getObject({
      Bucket: bucketName,
      Key: filename,
    })
    .promise();
  Logger.log(`downloadFile result: ${result.ETag}`);

  return result.Body as Buffer;
}
@Get(':id')
@UseGuards(CookieAuthGuard)
async findBoardById(
  @Param('id', ParseIntPipe) id: number,
  @Res() res,
): Promise<void> {
  const found = await this.boardService.findBoardById(id);
  // AES 복호화
  if (found.content) {
    found.content = decryptAes(found.content); // AES 복호화하여 반환
  }

  // 폼 데이터 만들어 반환
  const formData = new FormData();
  formData.append('id', found.id.toString());
  formData.append('title', found.title);
  formData.append('content', found.content);
  formData.append('author', found.user.nickname);
  formData.append('created_at', found.created_at.toString());
  formData.append('updated_at', found.updated_at.toString());
  formData.append('like_cnt', found.like_cnt.toString());

  // NCP Object Storage 다운로드
  const files = [];
  for (let image of found.images) {
    const file: Buffer = await this.boardService.downloadFile(image.filename);
    console.log(file);
    formData.append('file', file, {
      filename: image.filename,
      contentType: image.mimetype,
    });
  }

  res.set({
    'Content-Type': 'multipart/form-data',
  });
  formData.pipe(res);
  // return found;
}

다운로드는 컨트롤러에서 개별 파일 다운로드하는 서비스 메소드인 downloadFile을 호출해서 순서대로 폼데이터에 넣고, @Res() 데코레이터로 가져온 Response 객체에 전달한다.

결과 화면

  • 업로드
스크린샷 2023-11-23 오후 2 08 43
  • 다운로드
스크린샷 2023-11-23 오후 2 08 35

학습메모

  1. 잘못된 ncloud 공식문서 (ncloud financial)
  2. 올바른 endpoint 주소(일반 ncloud)

소개

규칙

학습 기록

[공통] 개발 기록

[재하] 개발 기록

[준섭] 개발 기록

회의록

스크럼 기록

팀 회고

개인 회고

멘토링 일지

Clone this wiki locally