Posts AWS API Gateway에서 CORS 해결하기
Post
Cancel

AWS API Gateway에서 CORS 해결하기

CORS

기능적 개요

교차 출처 리소스 공유 표준은 웹 브라우저에서 해당 정보를 읽는 것이 허용된 출처를 서버에서 설명할 수 있는 새로운 HTTP 헤더를 추가함으로써 동작합니다. 추가적으로, 서버 데이터에 부수 효과(side effect)를 일으킬 수 있는 HTTP 요청 메서드(GET을 제외한 HTTP 메서드)에 대해, CORS 명세는 브라우저가 요청을 OPTIONS 메서드로 “프리플라이트”(preflight, 사전 전달)하여 지원하는 메서드를 요청하고, 서버의 “허가”가 떨어지면 실제 요청을 보내도록 요구하고 있습니다. 또한 서버는 클라이언트에게 요청에 “인증정보”(쿠키, HTTP 인증)를 함께 보내야 한다고 알려줄 수도 있습니다.

CORS 실패는 오류의 원인이지만, 보안상의 이유로 JavaScript에서는 오류의 상세 정보에 접근할 수 없으며, 알 수 있는 것은 오류가 발생했다는 사실 뿐입니다. 정확히 어떤 것이 실패했는지 알아내려면 브라우저의 콘솔을 봐야 합니다.

이후 항목에서는 시나리오와 함께, 사용한 HTTP 헤더의 상세 내용을 다룹니다.

CORS는 자바스크립트로 웹개발을 해보신분이라면 누구나 만나는 오류 중 하나입니다. 위 글을 짧게 설명하면 CORS는 서로 다른 도메인의 사이의 데이터 전송을 허용해주는 웹브라우저의 기술이자 표준입니다. 만약 내 브라우저의 웹 애플리케이션이 다른 도메인의 서버와 아무런 제약없이 통신할 수 있다면, 우리는 CSRF, XSS 와 같은 공격에 노출될 것 입니다.

하지만, 웹 개발을 하는 우리는 수도없이 다른 도메인의 서버와 통신을 해야합니다. 예를들면 API Gateway에 HTTP API들을 생성하는것 조차 AWS 기반의 도메인과 통신해야 한다는 것을 의미합니다. 주로 CORS오류는 수많은 API를 응답받아 처리해야 하는 프론트엔드 개발자가 자주 접합니다. 이는 백엔드 개발자와 서로 소통하여 해결하는 문제입니다.

해결책은?

간단히 “Hello from CORS!” 문자열을 응답에 실어보내는 람다함수를 생성했습니다.

1
2
3
4
5
6
7
8
9
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from CORS!')
    }

이를 호출할 수 있도록 API Gateway에 https://jrst6j8v8f.execute-api.us-east-1.amazonaws.com/dev/cors 경로로 GET 요청을 받는 리소스를 생성하고 위의 람다함수와 연결했습니다.

다음은 우리가 개발중인 로컬호스트에서 API Gateway로 GET 요청을 하는 자바스크립트 코드입니다.

1
2
3
4
var url = 'https://jrst6j8v8f.execute-api.us-east-1.amazonaws.com/dev/cors'
$.get(url, function (data, status) {
  console.log(data)
});

크롬브라우저를 열고 위 스크립트를 실행하면 아래와 같이 CORS 관련 오류가 발생하고 , GET 요청이 실패하게 됩니다. 이유는 우리 웹프로그램의 도메인(localhost)과 “Hello from CORS!”를 제공해주는 API Gateway의 도메인(rst6j8v8f.execute-api.us-east-1.amazonaws.com)이 서로 다른 상황에서 우리 측에서 무작정 리소스를 요청했기에 오류가 발생한 것 입니다.

AWS API Gateway에서 CORS 해결

API Gateway 탭에서 CORS를 클릭하여, Access-Control-Allow-Origin에 * 을 입력하고 저장해주면 모든 오리진을 허용합니다. 현재는 테스트용이라 모든 오리진을 허용했지만 추후 실제 서버에 웹어플리케이션을 배포시 해당 서버의 도메인과 맞춰주셔야 보안적으로 안전합니다.

  1. API Gateway를 HTTP API형식으로 생성하고 미리 “도메인/dev/cors” 경로로 리소스를 생성해놨습니다

  2. API Gateway CORS 탭으로 이동후 Access-Control-Allow-Origin 을 수정하기 위해 구성을 클릭합니다

  3. Access-Control-Allow-Origin에 * 을 입력하고 추가를 누른뒤 저장을 누릅니다

  4. 브라우저를 리프레시하면 CORS에 의해 다른 도메인임에도 GET 요청이 성공하여 “Hello from CORS!”를 콘솔에 출력합니다

정리

오늘은 아주 간단히 HTTP Request에서 왜 CORS 오류가 일어나는지 알아봤습니다. 그 후 CORS를 해결하기 위해 AWS 콘솔로 Access-Control-Allow-Origin 헤더에 * (모든 오리진)을 추가해주었습니다.

CORS를 해결하기 전에는 서버가 응답하는 헤더에 Access-Control-Allow-Origin 헤더가 존재하지 않습니다.

CORS를 해결 후에는 Access-Control-Allow-Origin : * 로 새로운 헤더가 설정되어 응답이 옵니다.

앞에서 말씀드렸듯이, CORS는 브라우저의 표준입니다. CORS를 해결하기 전,후 모두 서버 측으로 부터 응답을 받습니다. 하지만, 리퀘스트 헤더와 응답 헤더의 CORS관련 헤더를 비교하여 브라우저가 해당 응답을 사용할 지 말지 결정하는 것입니다. 이 부분은 꼭 숙지하시면 좋겠습니다.

추가적으로 OPTION 메소드로 preflight 요청을 보내 서버에 사전 요청을 하는 개념도 있습니다. 이 부분은 다음 포스팅에서 다뤄보겠습니다.

참고

CORS

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

This post is licensed under CC BY 4.0 by the author.

Vue.js 개발할 때 같이 사용하면 좋은 라이브러리

CSS 주요 내용 정리

Comments powered by Disqus.