본문 바로가기

AWS

웹 앱에서 AWS S3에 파일 올리는 방법

 

AWS의 콘솔에서 S3에 파일을 직접 올리는 방법도 있지만

앱에서 사용자가 파일을 올릴 수 있게 하려면 web에서 javascript 코드를 이용해 파일을 올리는 방법을 알아야 한다.

 

먼저 준비 해야 할 것들

1. 버킷 생성과 접근 권한 설정

 

버킷(저장소)를 먼저 만들고 권한 설정을 해야 한다.

thinkforthink.tistory.com/280

 

2. 버킷의 CORS 설정

 

버킷의 권한 탭에서 CORS 항목의 편집 버튼을 클릭해 다음 설정을 넣는다.

[
  {
    "AllowedHeaders": [
        "*"
    ],
    "AllowedMethods": [
        "PUT",
        "POST",
        "DELETE"
    ],
    "AllowedOrigins": [
        "*"
    ],
    "ExposeHeaders": []
  }
]

AllowedOrigins를 *로 설정하면 모든 곳에서 버킷의 파일에 접근할 수 있게 된다.

이 설정은 CORS와 관련된 설정일 뿐 1에서 언급한 접근 권한 설정과는 별개이니 착각하지 않도록 한다.

자세한 내용은 다음을 참고하자.

docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

 

3. IAM에서 사용자 추가

 

AWS에 가입한 계정을 root라 하고

root 아래에 여러 사용자를 추가해서 쓸 수 있다.

한 계정에서 root는 운영자이고, 다른 사용자를 관리자로 두는 것과 유사하다.

 

여러 앱을 만들 수 있는 한 계정에서 하나의 앱에 모든 권한을 주는 것은 

여러 집을 가진 집주인이 세입자에게 모든 집의 키를 주는 것과 같다.

 

S3에 파일 올리는 기능을 구현하려면 AWS의 IAM에서 사용자를 추가해야 한다.

이 과정에서 사용자의 accessKeyId와 secretAccessKey를 얻을 수 있다.

이를 이용해서 AWS는 사용자의 신원을 파악할 수 있고

IAM에서 사용자에게 부여된 권한에 따라 앱에서 요청한 파일 업로드 등을 허가하거나 제한한다.

 

IAM에 사용자를 추가하는 방법은 다음을 참고하자.

docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html

 

잘 모르겠으면 사용자가 모든 것에 접근 할 수 있도록 설정하자.

후에 수정해도 된다.

그리고 코드에서 사용할 accessKeyId와 secretAccessKey를 잘 기록해 두자.

 

이제 코드를 작성하자.

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://sdk.amazonaws.com/js/aws-sdk-2.809.0.min.js"></script>
</head>
<body>
  <input id="files" type="file" />
  <button id="button">올리기</button>
  <script src="putFile.js"></script>
  <script src="index.js"></script>
</body>
</html>

head에서 aws-sdk를 script 태그로 불러오고

아래와 같이 파일을 불러올 수 있는 input과 button 엘리먼트를 생성한 뒤

putFile.js와 index.js를 실행한다.

 

Index.js

// index.js

const button = document.getElementById('button');
button.addEventListener('click', () => {
  const input = document.getElementById('files');
  putFile(input.files[0]);
})

버튼을 클릭하면 input에서 파일 선택으로 불러온 파일 객체를 받아 putFile의 인자에 넣고 putFile 함수를 호출한다.

 

putFile.js

const putFile = file => {
  const albumBucketName = '    '; // S3의 버킷 이름
  const region = 'ap-northeast-2'; // 서울
  const accessKeyId = '    '; // IAM에서 생성한 사용자의 accessKeyId
  const secretAccessKey = '    '; // IAM에서 생성한 사용자의 secretAccessKey
  
  AWS.config.update({
    region,
    accessKeyId,
    secretAccessKey
  }); 
  
  const upload = new AWS.S3.ManagedUpload({
    params: {
      Bucket: albumBucketName,
      Key: file.name,
      Body: file,
      ACL: "public-read"
    }
  });
  
  const promise = upload.promise();

  promise.then(
    function(data) {
      console.log("Successfully uploaded photo.");
    },
    function(err) {
      return console.log("There was an error uploading your photo: ", err.message);
    }
  );
};

albumBucketName에는 버킷 이름을 넣는다.

accessKeyId와 secretAccessKey에는 IAM에서 생성한 사용자의 키를 넣는다.

이런 설정 값들은 dotenv 등을 이용해서 환경변수로 저장하는 게 편하다.

 

error가 발생하지 않고 Successfully uploaded photo라는 콘솔 메시지가 뜨면 버킷에서 업로드를 요청한 파일을 확인할 수 있다.

 

참고 :

docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html

stackoverflow.com/questions/47535820/how-can-i-upload-the-image-to-aws-s3/47536198

 

node 환경에서 사용하려면 다음 github 코드를 참고하자.

github.com/socratone/simple-sdk-s3.git