본문 바로가기

개발

Cloudfront Serving. 그런데, CORS?

서비스가 이미지나 비디오를 서빙해야하는 경우라면 CDN은 거의 필수적으로 고민하게 된다.

AWS환경이라면 Cloudfront를 고민하게되고, 거의 기본적으로 S3를 Origin으로 하는 Distribution을 만들어서 사용하게 된다.

애초에 CORS를 고민하고 시작했으면 크게 문제가 되지 않았겠지만, 그렇지 않았다면 여기서부터 문제가 많-이 생기게 된다.

 

잠깐 CORS란? 

더보기

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다. 

출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

좀 쉽게말하면, 어플리케이션에 종속되어있는 리소스가 아니면, 접근할 권한이 필요하다는 것이다. 

 

이게 문제가 되는 이유는 고전적인 서비스 환경에서는 애초에 CORS같은걸 고려하지 않게 하거나, 모두 허용같은 정책을 서버에서 설정하고 개발하던 경우가 많았기 때문인데, AWS(Cloudfront)에서는 이런 모든 것들을 예민하게 따지고 있기 때문이다. 

때문에 AWS를 사용하더라도, S3를 몽땅 퍼블릭하게 열어서 그대로 S3도메인채로 서빙하는 방식을 사용했다거나, 어플리케이션에서 직접 S3 Client를 이용해서 서빙하는 방식을 사용했다면 느낄 수 없는 문제였던 것이다.

 

 

1. 개발 환경에서 발생하는 CORS문제

개발의 편의를 위해 변경된 코드들을 매번 AWS환경에 올려서 서빙하는 방식이 아닌 localhost에서 테스트하고 어느정도 개발하고나면 배포해서 진행하게 되는데, 개발 도메인이 별도로 세팅된 경우가 아니라면 Origin이 다르기 때문에 문제가 발생한다.

예) localhost에서 abc.com/image.jpg를 요청하는 경우와, abc.com에서 abc.com/image.jpg를 요청하는 것은 엄밀히 다르다.

이 경우에는 S3의 정책을 아래와 같이 기본적으로 AllowedOrigins을 *로 허용하게 해주고, Cloudfront 에서는 S3(Origin)의 설정을 그대로 따라가게 하면 된다.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]

 

2. Webapp을 개발하고 있습니다. 그런데 위와 같이 설정했는데, CORS에러가 랜덤하게 발생해요.

일반적으로 어플리케이션에서 바로 CDN의 이미지만 서빙하는 구조라면 문제가 없겠지만, 웹앱에서 XHR을 통해서 특정 이미지나 비디오를 가져와서 표시해준다면, CORS가 발생 할 수 있다. 

Cloudfront가 오동작을 하는건지, 브라우저의 캐시가 오동작하는건지 (둘다 의심스럽다) CORS관련 헤더가 없는 채로 캐시가 되는 경우들이 종종 존재해서 위와 같은 상황이 발생하는것으로 보이고, Cloudfront Function을 이용해서 CORS헤더가 없으면 무조건 추가하도록 설정하면 해결된다. (이전에는 Lambda@Edge를 사용해야겠지만, Cloudfront Function이 이런 목적에 맞게끔 사용하라고 나온 듯 하다)

function handler(event)  {
    var response  = event.response;
    var headers  = response.headers;

    // If Access-Control-Allow-Origin CORS header is missing, add it.
    // Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation.
    if (!headers['access-control-allow-origin']) {
        headers['access-control-allow-origin'] = {value: "*"};
        console.log("Access-Control-Allow-Origin was missing, adding it now.");
    }

    return response;
}

 

'개발' 카테고리의 다른 글

25년  (1) 2025.05.05
M1 Mac OS 12 beta 6 - Jetbrain Tool 실행하기  (0) 2021.09.14
AWS에서 Serverless 배포 생각정리  (0) 2021.07.25
ECS with ALB  (0) 2021.07.15
EC2, Fargate, Lambda. 뭐쓰지?  (0) 2021.07.10