본문 영역

DevOps/AWS2019. 6. 3. 11:12

다른 도메인(Cross Origin)에 존재하는 이미지를 HTML Canvas에 로딩시 아래와 같은 Access-Control-Allow-Origin Header 세팅이 되지 않아 이미지 로딩 자체가 block 되었다라는 브라우저의 오류 메세지를 종종 접할 수 있다.

 

Chrome 브라우저의 CORS 오류

 

AWS의 파일 스토리지 서비스인 S3와 CDN 서비스인 CloudFront를 조합해서 파일 스토리지 및 캐싱을 구현하는 경우 매우 흔하게 접하는 문제중 하나이다. 스마트링크의 Uploader 컴포넌트 또한 브라우저에서 사용자가 선택한 이미지를 S3로 업로드하고 CloudFront를 통해 캐싱된 파일을 다운로드 하는 방식이기 때문에 Uploader 컴포넌트를 사용하는 서비스에서는 필수적으로 세팅해야하는 부분이다.

 

많은 웹 개발자들이 파일 처리 관련 개발시 빈번하게 접하는 이슈이나 근본적인 해결책을 찾지 못해 Stack Overflow등을 검색하여 간략한 how-to만으로 임기응변하는 경우를 자주 목격한다. (네이버에서 CORS 키워드로 검색해 보면 형편없는(?) 한글 검색 결과들만 보이는 것도 이유중에 하나일까? IT 강국의 1등 검색포털엔진의 개발관련 검색 결과는 참으로 놀랍다!)

 

우선, CORS에 대한 개념부터 제대로 알고 접근하자.

CORS란?

Cross Origin Resource Sharing의 약자로 사실상 더 설명이 필요없지 않은가? 더 이상의 설명은 생략한다!!! 

 

현재 웹페이지가 이 페이지를 제공한 서버(Origin)가 아닌 다른 서버(Cross Origin)에게 자원(이미지, 파일, 스크립트 등등)을 요청/호출하는 것을 의미한다. 가장 쉬운 예로 CDN에 배포되어 있는 이미지등을 단순 link를 통해 <img>태그로 로딩하는 것도 CORS라고 할 수 있다. 

 

가장 흔한 악용 사례를 생각해보자면, 현재 페이지에서 다른 서버의 자원 중 단순 이미지 또는 파일이 아닌 악성 스크립트를 로딩한다라는 상황을 상상해보면 CORS가 왜 살짝 까다로울 수 밖에 없는지 금방 이해될 것이다.

 

일반적인 경우는 브라우저의 기본 기능을 통해 이미지(또는 파일)를 직접 다운로드를 하거나 DOM을 이용해 (<img> 테그나 CSS) 이미지를 표시하기 때문에 문제 되는 경우가 거의 없다. 하지만 XHR을 통해 데이터를 받아서 처리해야하는 특수한 경우(예: Smartlink의 Uplaoder 컴포넌트의 Cropper)에는 웹앱이 제공되는 도메인과 CloudFront 서비스의 도메인이 다르기 때문에 CORS 관련 문제가 발생한다. 물론 AWS S3에서 CORS 관련 설정을 제공하나, 브라우저와 CloudFront의 캐쉬기능과 엮이면서 재대로 동작하지 않는 경우가 빈번하다.

 

AWS에서의 CORS 세팅 방법

1. S3 > Permissions > CORS configuration

S3에 접속하여 CORS를 설정하고자 하는 Bucket의 Permissions (탭) > CORS configuration을 선택한다. 아래 그림에서와 같이 <AllowedHeader> 태그를 추가한다. 특정 Oring에 대해서만 허용하는 경우 해당 도메인을 입력하고 모든 Origin의 요청에 대해 CORS를 허용할 경우 "*" 를 입력한다.

 

2. CloudFront > Origin Access Identity

CloudFront의 접속하여 Origin Access Identity를 하나 생성 후 Amazon S3 Canonical User ID를 복사해 둔다.

3. S3 > Permissions > Bucket Policy

다음으로는 Bucket Policy를 선택하고 아래 내용을 입력한다. 

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Grant a CloudFront Origin Identity access to support private content",
            "Effect": "Allow",
            "Principal": {
                "CanonicalUser": "b4a159fd...b9a236f1841c3470a188ed80b53d77edd3ce69f"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::home.image/*"
        }
    ]
}

중요 부분은 조금 전 복사한 CloudFront의 Origin Access Identity 값을 CanonicalUser 키의 value로 세팅해야 하고, Resource키의 value 부분은 상기에서 CORS를 설정한 버킷이름으로 세팅해야 한다. 저장하고 난 뒤 다음과 같은 결과를 확인할 수 있어야 한다.

4. CloudFront > Origin Setting 

CloudFront의 Origin Setting으로 이동하여 Origin Access Identify를 'Use an Existing Identity'로 선택 후 이미 생성해 두었던 Origin Access Identity를 선택하여 설정한다.

5. CloudFront > Behavior

이번엔 CloudFront의 Behavior 탭을 선택한 후 CORS 설정을 한 S3 Origin을 선택한 후 Edit 버튼을 눌러 CloudFront의 Caching 처리 방식을 변경해야 한다.

Cache Based on Selected Request Headers를 "None"에서 "Whitelist"로 변경하고 아래와 같이 3개의 헤더를 추가한다.

6. Testing

 

curl CLI를 통해 해당 버킷 내에 캐싱된 파일의 URL을 테스트하여 header 응답이 아래와 같이 200 값을 반환하면 세팅이 제대로 완료된 것이다. 

작성자

account_circle
grooveslap

댓글 영역