2017년 6월 13일 화요일

[AWS] AWS S3를 Origin으로 설정한 CloudFront의 컨텐츠 갱신

AWS S3를 Origin으로 설정한 CloudFront의 컨텐츠 갱신

이전 포스팅에서 AWS S3를 Origin으로 설정해서 CloudFront의 distribution을 생성하는 방법을 정리해보았습니다.
(링크 : https://walkinpcm.blogspot.kr/2017/06/aws-aws-s3-static-website-hosting.html)
그런데 해당 포스팅을 공유했던 페이스북 게시글을 통해서 S3의 파일을 갱신했을 때 CloudFront에는 어떻게 갱신(재배포)하는지 질문을 주셨습니다.
해당 질문에 관해서 감사하게도 여러 분들께서 좋은 답변을 주셔서 저도 도움이 많이 되었습니다.
그래서 이번 포스팅에서 그 S3의 파일이 갱신되었을 때, CloudFront에 어떻게 갱신하는지 정리해보려합니다.

1. CloudFront의 기본 캐싱 기간

CloudFront에 배포된 컨텐츠는 기본적으로 24시간 동안 캐싱된다고 합니다.
그래서 S3의 원본 파일을 갱신하면 24시간 후에는 갱신한 파일로 변경됩니다.

2. 즉시 CloudFront 배포의 캐시를 지우기

이 방법은 CloudFront의 배포(distribution)에 저장되어 있는 캐시를 즉시 지워버려서 클라이언트의 요청이 들어왔을 때, 새롭게 Origin에서 컨텐츠를 가져오도록 하는 방법입니다.
배포된 캐시를 지우려면 Invalidations 기능을 이용합니다.
배포의 Invalidations 탭에서 Create Invalidation을 클릭합니다.
Object Paths에 친절하게 입력 예시가 나오는데, 예시처럼 특정 파일을 입력하거나 와일드카드(*)를 이용하여 경로를 입력하고 Invalidate를 클릭하면 입력한 파일들이 바로 배포에서 지워집니다.

입력 예시는 공식 문서에 자세하게 나와있습니다.
(링크('무효화 경로'를 찾으세요) : http://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#invalidation-specifying-objects )
Invalidate를 하자마자는 Status가 'In Progress'라고 표시되는데, 모든 엣지에서 지워지면 'Completed'로 변경됩니다.

3. 배포된 전체 컨텐츠 캐싱 시간 변경

CloudFront 배포(distribution)의 설정에서 전체 컨텐츠에 대한 갱신 주기를 설정할 수 있습니다.
해당 배포의 Behaviors 탭으로 갑니다.
배포를 생성할 때 설정된 항목이 하나 있습니다. 체크박스를 선택하고 Edit을 클릭합니다.

그러면 설정 변경화면이 나오는데, 여기서 Object Caching항목을 Customize로 선택합니다.
Customize를 선택하면 아래 3개 칸(Minimum TTL, Maximum TTL, Default TTL)이 활성화됩니다.
(각각에 대한 자세한 설명 : http://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesObjectCaching)

Default TTL은 특정 객체에 HTTP Header를 지정하지 않은 오리진 객체에만 적용되는 값이고, Maximum TTL은 HTTP Header를 지정한 오리진 객체에만 적용되는 값입니다.
그래서 전체 컨텐츠에 대한 캐싱 시간을 변경하려면 Default TTL을 수정합니다. 초단위로 수정하시면 됩니다.
수정 완료하시면 배포의 상태가 In Progress가 되고 배포가 완료되면 Deployed로 변경됩니다.

4. S3에 저장된 특정 객체의 캐싱 시간 변경

S3의 특정 객체의 갱신주기만 따로 설정하려면 해당 객체에 metadata를 설정하면 됩니다.
S3에서 갱신주기를 설정할 객체를 선택합니다. 객체의 이름 부분을 선택하면 해당 객체에 대한 Overview가 나타나는데,
바로 옆에 Properties 탭을 선택합니다.

Properties 중에 Metadata를 클릭합니다.
그러면 Add Metadata 버튼이 있는데 여기를 클릭합니다.
Key 목록에서 Cache-Control 또는 Expires를 선택합니다.
Cache-Control로 선택하면 CloudFront 캐시에 머무르는 시간을 초단위(형식 : max-age=초)로 입력해주시면 되고,
Expires를 선택하면 캐시에 머무를 특정 날짜를 입력하시면 됩니다.(형식 : Sat, 27 Jun 2015 23:59:59 GMT)
(날짜 포맷 : https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1)



지금까지 S3를 Origin으로 한 CloudFront의 배포 즉시갱신/갱신 주기 설정 방법을 정리해보았습니다.
4가지 방법을 다 해보니.. 캐싱 시간을 변경하는 방법은 조금 부정확한 감이 있습니다. 캐싱 주기 시간이 지나고 최신 파일을 읽어왔다가 새로고침하면 다시 예전 파일을 읽어오더라구요.. 아마 모든 엣지마다 다시 배포되는 시간이 달라서 그런가 싶습니다..
혹시 본문 내용중 틀린 부분을 댓글로 남겨주시면 감사히 바로 수정하도록 하겠습니다.
감사합니다.

참고링크

2017년 6월 12일 월요일

[AWS] AWS S3를 이용한 static website hosting에서 Custom Domain과 HTTPS(SSL) 사용하기

AWS S3를 이용한 static website hosting에서 Custom Domain과 HTTPS(SSL) 사용하기


지금은 많은 사람들이 알고 있듯이, AWS S3를 이용하면 단순 파일 저장뿐 아니라 정적 웹호스팅(static website hosting)이 가능합니다.
그런데, 한가지 아쉬운 점은 S3에 업로드한 객체들 각각의 endpoint는 https가 기본지원되는 반면에, web hosting의 endpoint는 http만 지원하고 있습니다.
하지만 AWS CloudFront를 이용하면 S3의 web hosting에도 https를 사용하게 할 수 있습니다.
이번 포스팅에서는 S3를 이용한 static website hosting에서 Custom Domain과 HTTPS(SSL) 사용하는 방법을 정리해보겠습니다.

0. 사용하는 AWS 서비스

이번 포스팅에서는 4가지 AWS 서비스를 사용합니다.
  • Certificate Manager
    • SSL 인증서 생성.
  • S3
    • 웹호스팅 Origin.
  • CloudFront
    • 웹호스팅 파일들을 CDN에 올리고 SSL을 적용. 그리고 Custom Domain 설정.
  • Route53
    • CloudFront에 배포한 웹호스팅 도메인과 Custom Domain을 연결.

1. SSL 인증서 준비

본 포스팅에서는 HTTPS를 위한 SSL 인증서를 AWS Certificate Manager 서비스에서 만듭니다.
절차는 쉽지만 알아둬야할 사항이 있어서 글로 정리합니다.
(참고로, AWS Certificate Manager에서 만드는 SSL인증서는 무료입니다!)
우선, Certificate Manager 서비스에 들어갑니다.
가장 먼저 해줘야할 작업은 리전을 US East (N. Virginia)로 변경하는 것입니다.
왜냐하면, CloudFront에서 Custom SSL Certificate를 사용하려면 반드시 Virginia 리전에서 생성된 인증서만 허용되기 때문입니다.


리전을 바꿨으면 시작하기를 선택합니다.



도메인 이름은 인증서를 발급 받고 싶은 도메인 주소를 입력합니다.
ssltest.example.com 처럼 서브도메인을 포함한 주소를 입력해도 되고, *.example.com 처럼 서브도메인을 와일드카드로 입력해도 됩니다.
입력하고나면 검토 및 요청을 클릭합니다.



다음화면에서는 도메인 관리자에게 인증서 승인을 위한 메일을 보낸다는 안내가 됩니다.
확인 및 요청을 클릭합니다.



다음화면에서는 어떤 메일로 승인 요청을 보냈는지 나타납니다.(도메인 부분을 클릭하면 펼쳐집니다.)



계속 버튼까지 눌러줍니다.
(생성한 인증서 목록이 보일텐데 방금 만든 인증서의 상태가 '검증 보류'라고 나타날 겁니다.)
사실 승인 요청을 메일로 보내기 전에 위의 메일 주소들 중에 하나라도 생성되어 있어야하는게 맞는데...
제 경우에는 도메인을 Route53에서 만들었었더니, whoisprivacyservice.org 계정 3개로 보내진 인증서 승인 메일이 제 개인 메일로 전달(forwarding)되어져 왔습니다.
아래 그림 처럼 메일이 왔습니다.
가운데 쯤의 Amazon Certificate Approvals 링크를 누릅니다.



그러면 새창이 또 뜹니다. 여기서 I Approve 버튼을 누르면 인증서 승인이 완료됩니다.



승인이 완료되고 다시 Certificate Manager로 돌아와서 새로고침을 한번 해주면 상태가 '발급 완료'로 변경됩니다.
인증서 준비는 끝났습니다~!

2. S3 준비

S3에 버킷을 생성하고 파일들을 업로드 하고 버킷의 Properties에서 Static website hosting 기능을 활성화합니다.


버킷을 생성할 때 주의할 점이 하나 있습니다.
HTTPS 지원없이 Custom Domain만 사용하려면 Route53에서 S3를 바로 연결시키면 되는데, 이때는 버킷 이름이 Custom Domain이름과 같아야합니다. (ex. ssltest.example.com 으로 버킷 이름도 설정하고 도메인도 똑같은 이름으로 만들어야합니다.)
그런데 CloudFront를 S3와 Route53 사이에 껴넣을때는 버킷이름이 도메인 이름이랑 같으면 오히려 HTTPS 지원이 정상적으로 안됩니다. 제가 이 문제 때문에 하루를 버렸네요..ㅠㅠ
다시 본론으로.. 버킷의 Properties에서 Permissions에 가셔서 Bucket Policy에 아래 내용을 입력하고 Save합니다. Resource의 값 부분에 있는 [YOUR_BUCKET_NAME]을 본인의 버킷 이름으로 대체하시면 됩니다.
아래 Bucket Policy는 버킷으로 웹호스팅 할 때 전체 파일에 대해서 모든 사용자한테 Get을 허용하는 유용한 Policy입니다.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[YOUR_BUCKET_NAME]/*"
        }
    ]
}

3. CloudFront 준비

CloudFront는 AWS의 CDN 서비스입니다.
AWS CloudFront 서비스에 들어가서 Create Distribution을 선택합니다.



다음 화면(Select delivery method)에서는 배포할 컨텐츠의 타입이 무엇인지 선택합니다.
여기서는 Web부분의 Get Started를 클릭합니다.



다음 화면(Create distribution)에서는 갖가지 설정들을 하게되는데, 필수적인 사항만 정리하겠습니다. 다른 설정들은 상황에 따라 알맞게 손 보시면 됩니다.
Origin Settings에서 Origin Domain Name을 입력합니다.
마우스로 선택하면 S3 버킷 목록이 나오는데, 목록에서 선택하시지 말고,
위의 S3에서 웹호스팅 기능을 활성화 했을 때 생성되는 Endpoint(URL)을 직접 복사해서 넣으시길 권장드립니다.
목록에서 버킷을 선택해도 일반적인 static 웹호스팅은 문제가 없으나, SPA(Single Page Application)을 웹호스팅 할 경우를 대비한다면 Endpoint(URL)을 직접 입력해야합니다.
(If you want to host SPA(Single Page Application) on S3, insert Web hosing Endpoint(URL) of S3 into 'Origin Domain Name'. Don't select one of the dropdown list.)



Distribution Setting에서 Alternate Domain Names에 사용할 Custom Domain을 입력합니다. 이 이름은 나중에 Route53에 생성할 도메인과 동일해야합니다.
SSL Certificate는 Custom SSL Certificate를 선택합니다.
Default로 선택해도 동작에는 문제가 없지만 아래 그림처럼 경고가 뜹니다. 도메인 이름과 인증서 이름이 같지 않아서 발생하는 경고입니다.
노력해서 HTTPS를 쓰려고하는데 이런게 보이면 영 꺼림직 하지요..
그래서 Custom SSL Certificate를 선택하고 1번 단계에서 생성한 인증서를 선택해줍니다.

!!주의!! 1번 단계에서 생성한 인증서가 목록에 보임에도 불구하고 Custom SSL Certificate가 선택이 불가능하게 비활성화 되어 있을 수 있습니다.
찾아보니 이게 활성화 되는데는 인증서 생성 이후에 하루 정도가 걸릴 수 있다고 하네요... 저도 자고 일어나니 선택이 가능했습니다.

그리고 Default Root Object에는 도메인만 입력했을 때 바로 보여줄 파일이 무엇인지 설정하는 것입니다. 다들 아시는 index.html 로 입력하게 되실 것 같네요 ㅎㅎ



딱 4가지만 설정했습니다. 이렇게 설정하고 완료하면 생성한 Distribution의 General 속성에서 Distribution Status가 InProgress가 됩니다. 이 때가 각 엣지로 배포되는 중이라고 하네요.(조금 오래 걸립니다..)
배포가 완료되면 Deployed가 됩니다. 자동으로 되는게 아니니깐 새로고침 간간히 해서 확인해주세요~



Deployed를 기다리는 동안 Route53을 준비합니다.

4. Route53 준비

본 포스팅을 참고하시는 분들은 아마 자체 도메인을 이미 가지고 계실 것 같습니다.
그래서 Route53에 이미 기존에 사용하는 Hosted Zone이 있다는 가정하에 정리하겠습니다.


Route53의 Hosted zones에 가셔서 사용하실 도메인에서 Create Record Set을 선택합니다.
우측에 나타나는 입력창의 Name 입력칸에 CloudFront에서 Alternate Domain Names에 입력했던 서브도메인을 입력합니다.
(ex. Alternate Domain Names에 ssltest.example.com 이라고 입력했따면 Name 입력칸에 ssltest를 입력합니다.)
Type은 A - IPv4 address를 선택합니다.
그리고 Alias를 Yes로 선택합니다. 왜냐하면 CloudFront와 Route53을 연결할 때 별칭 리소스 레코드 세트를 사용하면 DNS 쿼리에 대한 요금이 지불되지 않는다고 합니다~!
Alias Target 입력칸을 클릭하면 CloudFront distribution에 위에서 생성한 distribution이 알아서 나타나있을 것입니다. 그걸 선택합니다. (Name을 입력해야 나타납니다.)
Create를 누르면 끝납니다.

5. 확인

이제 모든 절차가 끝났습니다. DNS에 도메인이 등록되는 시간을 잠시 기다리고나면 아래처럼 S3로 웹호스팅한 웹페이지가 HTTPS가 지원되는 걸 보실 수 있습니다!
수고하셨습니다~



* 내용 추가!
> S3에 업로드한 파일을 수정해서 다시 올렸을 때 어떻게 CloudFront에 갱신시키는지에 대한 내용을 아래 링크에 정리했습니다. 함께 보시면 좋을 것 같습니다~!
(링크 : https://walkinpcm.blogspot.kr/2017/06/aws-aws-s3-origin-cloudfront.html)

참고링크

2017년 6월 8일 목요일

[AWS] AWS S3를 이용해서 웹브라우저에서 사용할 수 있는 포토 앨범 만들기

AWS S3를 이용해서 웹브라우저에서 사용할 수 있는 포토 앨범 만들기

이번 포스팅에서는 AWS S3를 이용해서 웹브라우저에서 사진을 업로드하고 보고, 삭제 할 수 있는 포토 앨범을 만드는 예제를 정리해보겠습니다.
여기서 사용하는 예제는 이미 AWS에서 튜토리얼로 제공하는 예제이지만, 아직 한국어가 지원되지 않았고, 제 스스로 학습을 위해서 정리해서 글로 남겨봅니다.
(원문 : http://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html)

시나리오

이 예제에서는 아래 그림과 같이, 웹브라우저에서 AWS SDK를 이용해서 AWS S3에 사진앨범을 만들게 됩니다.

이 예제에는 포토앨범에 대해서 아래와 같은 기능이 포함되어 있습니다.
  • listAlbums
  • createAlbums
  • viewAlbums
  • addPhoto
  • deleteAlbum
  • deletePhoto

0. 선행 작업

이 예제를 진행하기 위해서 3가지 선행 작업이 필요합니다.

0-1. AWS S3 Bucket 만들기

포토앨범들을 저장하기 위한 Bucket을 하나 만들어 줍니다.
그리고 Bucket의 Permissions 설정에서 하위메뉴에 있는 CORS configuration에 아래의 문서를 복사하고 저장해줍니다.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

0-2. AWS Cognito Identity Pool 생성하기

이 예제에서 credentials을 획득할 수 있게 하기위한 Cognito Identity Pool을 생성합니다.
원문에서는 익명 사용자도 허용했지만, 저는 Cognito UserPool로 로그인 한 사용자를 대상으로만 실습을 진행해보겠습니다.
왜냐하면 로그인 하고 난 뒤에 로그인 한 사용자의 credentials로 AWS 서비스에 접근되는게 보고싶거든요 ㅎㅎ
Identity Pool을 생성하는 방법은 아래 링크를 참고하시면 좋을 것 같습니다.
(링크 : https://walkinpcm.blogspot.kr/2017/06/aws-aws-cognito-federated-identities.html)

0-3. Identity Pool 생성할 때 함께 생성된 IAM Role에 S3에 접근할 수 있는 Policy 추가하기.

원문에서는 IAM role을 생성하라고 되어 있는데, 그럴 필요 없습니다.
0-2 단계에서 Identity Pool을 생성할 때 IAM role이 함께 생성되는데, 그 role을 찾아서 거기에 S3에 접근 할 수 있게 하기위한 Policy를 추가해주면 됩니다.
이 과정을 조금 자세히 살펴 보겠습니다.
(1) Policy 생성
Identity Pool을 생성할 때 함께 만들어진 IAM role을 찾으시면 Inline Policies는 무언가 자동으로 만들어진게 있는데 Managed Policies에는 아무것도 없습니다.


Attach Policy를 눌러서 S3에 접근할 수 있는 Policy를 찾아서 추가하면 되는데, 이렇게 하면 기본적으로 모든 Bucket에 대한 권한을 주게 됩니다.
앨범으로 쓸 Bucket은 하나인데 다른 Bucket까지 권한을 주면 보안 측면에서 좋지 않은 건 당연합니다.
그래서 권한을 줄 Bucket만을 대상으로하는 Policy를 새로 생성합니다.
AWS IAM에서 좌측 메뉴의 Policies를 누르면 기본적으로 제공되는 Policy들이 나타납니다. 그리고 그 위에 보면 create policy가 있습니다. 클릭합니다.


다음 화면에서 Policy를 어떤 방식으로 생성할 건지 묻는데, 여기서는 Create Your Own Policy를 선택합니다.
왜냐하면 Policy에 작성할 내용은 원문에서 제공하고 있거든요.


Policy Name은 본인이 Policy를 식별할 수 있게 잘 지어주시면 되고 Description도 Policy에 대한 설명을 잘 작성해주시면 됩니다.
중요한건 Policy Document입니다. 여기에 아래 Json 문서를 복사하고 BUCKET_NAME을 앨범으로 쓸 Bucket이름으로 바꿔줍니다.
다 작성하고나면 Validate Policy 버튼을 눌러서 작성한 Policy가 올바른지 확인하고 확인이 되면 Create Policy 버튼을 클릭합니다.
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "s3:*"
         ],
         "Resource": [
            "arn:aws:s3:::BUCKET_NAME/*"
         ]
      }
   ]
}


(2) Cognito Identity Pool을 생성하면서 함께 생성된 Role에 방금 생성한 Policy 추가
Policy를 생성하고 나면 아까 Role에서 아무것도 없던 Managed Policies에 Attach Policy를 눌러서 방금 생성한 Policy를 추가해줍니다.


선행작업 3번째가 좀 길었네요.. 선행작업 여기까지입니다ㅎㅎㅎ 쉬었다가 아래부터는 웹브라우저에서 포토앨범을 만들 html, javascript 코드들을 보시죠 ㅎㅎ

1. HTML 코드 작성

HTML 코드는 간결합니다. 사실 원문에서는 더 간결한데, 원문에서는 익명사용자를 허용하기 때문에 로그인 할 필요가 없어서 더 짧은 것이고, 본 포스팅에서는 로그인을 한 사용자만 허용하기 위해서 코드가 조금 더 들어갔습니다.
<!DOCTYPE html>
<html>
  <head>
    <!--
        AWS Cognito를 사용하려면 아래 2개의 라이브러리가 필요합니다.
        자세한 사항은 https://walkinpcm.blogspot.kr/2017/05/aws-aws-cognito.html 를 참고해주세요.
     -->
    <script src="./res/js/aws-cognito-sdk.min.js"></script>
    <script src="./res/js/amazon-cognito-identity.min.js"></script>

    <!-- AWS SDK for Javascript -->
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.20.min.js"></script>

    <!-- 로그인, 앨범 관련 함수를 작성할 js 파일 -->
    <script src="./res/js/app.js"></script>

    <script>
       function getHtml(template) {
          return template.join('\n');
       }
    </script>
  </head>
  <body>
    <!-- 로그인을 위한 부분입니다. -->
    <div>
      <h1>Cognito Sign in</h1>
      Username : <input id="signin_username" type="text" size="20" placeholder="Username"><br>
      Password : <input id="signin_pwd" type="password" size="20" placeholder="Password"><br>
      <input type="button" onclick="submitSignin()" value="Sign in">
    </div>

    <h1>My Photo Albums App</h1>
    <!-- app div 내부에 함수들의 실행 결과가 출력될 것입니다. -->
    <div id="app"></div>
  </body>
</html>
코드를 실행하면 아래와 같이 스타일 없는 밋밋한 화면이 출력됩니다.
원문대로라면 앨범 리스트가 나와야하지만, 본 포스팅에서는 로그인에 성공하면 앨범 리스트가 출력되도록 수정하였습니다.


로그인에 성공하면 아래와 같이 표시됩니다.



2. Javascript 코드 작성

Javascript코드는 HTML의 head 내부에 script 태그로 넣어도 되지만, 내용이 조금 기니깐 따로 파일로 저장하시는게 좋습니다.
위의 HTML 코드에서도 보이듯이 저는 app.js 라고 파일을 작성해서 HTML 코드에서 불러왔습니다.
참고로, 제 포스팅의 코드와 원문의 코드가 조금씩 다른 부분은 다 로그인한 사용자만 허용하기 위해서 코드를 조금 수정한 것입니다.

2-1. AWS SDK와 AWS Cognito를 사용하기 위한 환경설정

// 리전 정보
var regionInfo = '<region>';

// 포토앨범으로 사용할 Bucket 이름
var albumBucketName = '<bucket-name>';

// 로그인 기능을 위한 Id 설정들
var userPoolId = '<user pool id>';
var appClientId = '<app client id>';    // 위의 userpool에서 생성한 app client id를 입력하시면 됩니다.
var identityPoolId = '<identity pool id>';  // 위의 userpool을 이용해서 생성한 federated identity pool의 id를 입력하시면 됩니다.

// AWS.config에 리전 정보 설정
AWS.config.update({
  region: regionInfo
});

// AWSCognito 객체에도 리전 정보 설정
AWSCognito.config.region = regionInfo;

// 사용할 User Pool의 정보를 저장
var poolData = {
  UserPoolId : userPoolId,
  ClientId : appClientId
};

// 입력한 User Pool 정보를 가지고 실제 User Pool에 접근할 수 있는 객체 생성
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);

// 로그인 성공시 로그인 한 사용자의 정보를 반환받는 변수
var cognitoUser;

// s3 객체를 담기 위한 전역변수 선언
var s3;
꺽인 괄호(<>)로 된 부분을 모두 자신의 정보로 대체해주시면 됩니다.
identityPoolId를 받기 위해서 AWS Cognito Federated Identitis에서 Identity Pool을 생성해야하는데,
이와 관련한 자세한 사항은 아래 링크를 참고하시면 좋습니다.
(링크 : https://walkinpcm.blogspot.kr/2017/06/aws-aws-cognito-federated-identities.html)

2-2. 로그인 함수

function submitSignin() {
  // 입력 폼에서 ID와 비밀번호를 입력받습니다.
  var user_Name = document.getElementById("signin_username").value;
  var user_Pw = document.getElementById("signin_pwd").value;

  // ID와 Password를 정해진 속성명인 Username과 Password에 담습니다.
  var authenticationData = {
    Username : user_Name,
    Password : user_Pw
  };

  // 여기에는 ID와 User Pool 정보를 담아 놓습니다.
  var userData = {
    Username : user_Name, // your username here
    Pool : userPool
  };

  // 로그인을 위해 Cognito 객체 2개를 준비합니다.
  var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
  cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);

  // authenticateUser 함수로 로그인을 시도합니다.
  cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function (result) {
      // credentials를 가져오기 위해 필요한 정보들을 입력합니다.
      AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: identityPoolId,
        Logins: {}
      });
      AWS.config.credentials.params.Logins['cognito-idp.' + regionInfo + '.amazonaws.com/'+ userPoolId] = result.getIdToken().getJwtToken();

      // get() 함수로 credentials을 획득합니다.
      AWS.config.credentials.get(function(err){
        if (err) {
          alert(err);
        }else{
          // !!! 주의 !!! S3 객체를 만들때는 credentials이 획득된 상태에서 S3를 생성해야합니다.
          // 그렇지 않으면, Missing credentials in config 에러가 발생합니다.
          s3 = new AWS.S3({
            apiVersion: '2006-03-01',
            params: {Bucket: albumBucketName}
          });

          // s3객체를 획득하고 앨범 리스트를 출력합니다.
          listAlbums();
        }
      });
    },
    onFailure: function(err) {
      alert(err);
    }
  });
}

2-3. 포토앨범 제어 함수

이 부분은 원문의 코드와 다른점이 없기에 상세한 설명은 생략하도록 하겠습니다.
다만, 원문의 오타인것인지 viewAlbum() 함수의 첫줄에서 슬래시가 2개면 정상적으로 안되고 1개면 정상적으로 되는 것 같더군요.
그래서 저는 슬래시 1개만 썼습니다.
관련해서 AWS에 Feedback을 남겼는데, 답변을 받아봐야 진상을 알 것 같네요 ㅎㅎㅎ
전체 코드를 보시려면 아래를 펼쳐주세요.
원문을 복사한것이 아니라 제가 작성해서 작동을 확인한 코드입니다.

모든 코드를 다 작성하시고, html 페이지를 웹브라우저에서 열으셔서 로그인을 하시면 앨범 목록이 보이고(처음엔 비었겠지만)
앨범을 생성하실 수 있습니다. 사진도 넣으실 수 있구요. 물론 사진 삭제도 됩니다.

다만 저도 아직 이상한 점은... 앨범을 생성하면 자동으로 빈껍데기 파일이 앨범안에 하나가 생성되더라구요..
코드 상에서 putObject가 있는데 일부러 넣은 것 같아서 뺄 수도 없고,,, 일단 좀 살펴봐야할 것 같습니다.
이 부분이 전체적인 기능에 문제가 되지는 않으니 일단 무시해도 될 것 같습니다~


여기까지해서 이번 포스팅을 마치겠습니다.
참고로, 본 포스팅의 코드가 제가 실습한 전체 코드입니다.
혹여 틀린 부분이나 보완되야할 부분을 댓글로 남겨주시면 최대한 빠르게 댓글 달고 수정하도록 하겠습니다~
감사합니다~!

참고 링크