개발일지

Presigned Url로 S3에 파일 업로드하기 본문

Infra, AWS, Linux

Presigned Url로 S3에 파일 업로드하기

lyjin 2023. 7. 16.

 

개요

이전 프로젝트에서 S3를 파일 서버로 사용했었습니다. 그 당시에는 url에 바로 접근할 수 있도록 모든 파일을 public으로 만들었습니다. 그러나 그렇게되면 모든 사람이 파일에 접근할 수 있기때문에 보안적으로 좋지않습니다.

이번 시간에는 파일을 안전하게 공유하기위한 방법 중 하나인 Presigned URL에 대해 알아보고 직접 사용해보고자 합니다.

 


Presigned URL이란?

미리 서명된 URL (Presigned URL)

말 그대로 미리 권한을 부여한 url을 말합니다. url 자체에 권한이 포함되어있기 때문에 별다른 자격증명 없이도 url에 접근할 수 있습니다. 또한 HTTP 기반으로 접근 가능하기때문에 웹 브라우저나 애플리케이션을 통해서도 손쉽게 접근 가능합니다.


생성자 가진 권한으로 임시 url을 생성해줄 수 있습니다. 생성할 때는 url의 만료기간과 Get, Put 등 HTTP 메서드를 지정해줄 수 있습니다. url은 설정한 기간안에서만 작업 가능합니다.

 


그 외 S3 파일 공유 방법

  • IAM 자격증명 공유하기
    Access Key Pair를 사용하는 방법입니다. 접근이 필요한 사람들에게만 자격증명을 공유할 수 있으나, 자격증명을 관리하기 어려우며 자격증명이 유출되거나 변경될 때마다 재공유해줘야한다는 단점이 있습니다. 또한 Access Key와 Secret Key는 영구 자격증명이기 때문에 보안이 뛰어나지 않습니다.
  • IAM 사용자 부여하기
    AWS API 또는 Assume Role 등을 통해 접근하는 방법입니다. 마찬가지로 지정한 사람들에게만 접근을 허용할 수 있지만 IAM 사용자 수가 5000개로 제한되어 있습니다. 그리고 모든 유저에게 IAM 사용자를 부여하는 과정이 필요하기 때문에 유지보수가 어렵습니다.

왜 Presigned URL를 사용할까?

보안 그리고 속도 측면에서 이점이 있습니다. 일반적인 API 요청에 비해 이미지를 업로드하는 것은 매우 부하가 큰 작업입니다. 이미지 파일 용량 자체가 크기 때문에 서버에서 이를 처리하게 된다면 속도도 느려질 뿐더러 서버가 다운될 수도 있습니다.


이 때 Presigned Url을 사용하면 서버를 거치지 않고도 클라이언트에서 바로 이미지를 S3에 업로드할 수 있습니다. 보통 권한 확인을 위해 서버를 한번 호출하게 됩니다. 그러나 이미 Presigned url을 생성하는 과정에서 보안 절차를 거쳤기에 별다른 과정 없이 바로 업로드할 수 있게 되는 것입니다.

 


Presigned URL 발급 받기

다음은 @aws-sdk를 사용해 Presigned url을 발급받는 예시입니다.

 

const client = new S3Client({
        region: REGION,
        credentials: {
            accessKeyId: ACCESS_KEY,
            secretAccessKey: SECRET_KEY
        }
    });

const command = new GetObjectCommand({
        Bucket: BUCKET_NAME,
        Key: key,
        ContentType: 'image/png'
    });

return await getSignedUrl(client, command, { expiresIn: 3600 });

 

GetObjectCommand 외에도 PutObjectCommand 등 원하는 메서드 작업을 지정해줄 수 있습니다. 이렇게 발급 받은 url을 reponse 하면 이 url을 가지고 클라이언트에서 바로 업로드할 수 있게 됩니다.