본문 바로가기

프로그래밍/[javascript] 자바스크립트

[javascript] CORS 오류 해결

by GenieIT* 2024. 10. 14.

728x90
728x90

 

1. CORS란?

  • CORS는 브라우저가 다른 출처(도메인, 프로토콜, 또는 포트)에서 리소스를 요청할 때 서버가 이를 허용할 수 있도록 하는 HTTP 헤더 기반의 보안 메커니즘입니다. 이를 통해 서버가 명시적으로 허용한 출처만이 그 서버에 접근할 수 있습니다.
  • JavaScript에서 CORS(Cross-Origin Resource Sharing) 오류는 브라우저 보안 메커니즘인 동일 출처 정책(Same-Origin Policy) 때문에 발생합니다. 동일 출처 정책은 웹 페이지에서 로드된 스크립트가 자신이 로드된 출처와 다른 출처의 리소스에 접근하는 것을 제한하여 보안을 강화합니다. 이 때문에, 자바스크립트로 다른 도메인에서 데이터를 요청하려 할 때 CORS 오류가 발생할 수 있습니다.

 

2. CORS 오류 메세지

  • CORS 오류는 주로 클라이언트(브라우저)와 서버 간에 올바르게 설정되지 않은 CORS 정책 때문에 발생합니다.

2-1. No 'Access-Control-Allow-Origin' header is present on the requested resource.

  • 서버가 요청에 대해 Access-Control-Allow-Origin 헤더를 제공하지 않아서 발생하는 오류입니다.

 

 

2-2. The 'Access-Control-Allow-Origin' header has a value that is not allowed.

  • 서버가 잘못된 출처(origin)를 허용하는 경우에 발생합니다.

 

3. COS 오류의 주요 원인

3-1. 동일 출처 정책 위반

  • 서버가 클라이언트로부터 요청된 출처를 허용하지 않으면 CORS 오류가 발생합니다. 동일 출처 정책에서 출처는 도메인, 프로토콜, 포트 번호로 정의되며, 이 세 가지가 동일해야만 다른 리소스에 접근할 수 있습니다.
  1. http://example.comhttps://example.com (프로토콜 다름)
  2. http://example.comhttp://api.example.com (서브 도메인 다름)
  3. http://example.com:80http://example.com:8080 (포트 다름)

 

 

3-2. 서버의 CORS 정책 미설정

  • CORS는 서버가 HTTP 응답에서 Access-Control-Allow-Origin 헤더를 통해 요청을 허용할 출처를 명시적으로 선언해야 합니다. 서버가 이 헤더를 설정하지 않으면 브라우저는 요청을 차단하고 CORS 오류를 발생시킵니다.
// 특정 도메인 허용
Access-Control-Allow-Origin: https://example.com
// 모든 출처 허용
Access-Control-Allow-Origin: *

 

 

3-3. 프리플라이트 요청(preflight request) 문제

  • CORS 요청 중 일부는 브라우저가 프리플라이트(preflight) 요청을 통해 서버가 요청을 허용하는지 확인한 후에 실제 요청을 전송합니다. 프리플라이트 요청은 HTTP 메서드가 GET, POST, HEAD가 아닌 경우, 또는 커스텀 헤더를 사용하는 경우에 발생합니다. 프리플라이트 요청은 OPTIONS 메서드를 사용하며, 서버가 이에 올바르게 응답하지 않으면 CORS 오류가 발생합니다.
OPTIONS /some-api-endpoint HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

 

 

3-4. 자격 증명(credentials) 문제

  • 쿠키, 인증 정보 등 자격 증명을 포함한 요청을 할 때는 서버가 다음과 같은 헤더를 포함해야만 클라이언트가 이를 사용할 수 있습니다. 그리고 클라이언트 쪽에서 요청 시 자격 증명을 포함하려면, 자바스크립트에서 credentials: 'include' 옵션을 사용해야 합니다.
  • 서버가 Access-Control-Allow-Origin을 *로 설정한 경우에는 Access-Control-Allow-Credentials: true와 함께 사용할 수 없으므로 특정 도메인을 명시해야 합니다.
Access-Control-Allow-Credentials: true
fetch('https://example.com/api/data', {
  method: 'GET',
  credentials: 'include' // 자격 증명을 포함한 요청
});

 

4. CORS 오류 해결 방법

4-1. 서버 측 해결

  • 서버에서 올바른 CORS 헤더를 추가해야 합니다. 서버의 언어와 프레임워크에 따라 다르지만, 일반적으로 서버에서 다음과 같은 헤더를 추가할 수 있습니다.
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

 

 

4-2. 프록시 서버 사용

  • CORS 문제를 피하기 위해 프록시 서버를 사용하여 브라우저와 서버 간의 중계를 할 수 있습니다. 프록시 서버는 동일 출처 정책을 우회하여 서버로부터 데이터를 받아 브라우저에 전달합니다.

 

 

4-3. JSONP (JSON with Padding)

  • CORS 문제를 우회하는 오래된 방법 중 하나로, JSONP는 script 태그를 사용하여 데이터를 가져오는 방법입니다. 이는 보안상 문제가 있을 수 있으며, 주로 구식 방식입니다. 대부분의 경우 CORS 해결 방법으로 JSONP를 권장하지 않습니다.

 

 

4-4. 프리플라이트 요청을 피하는 방법

프리플라이트 요청을 피하기 위해 요청을 단순하게 만들 수 있습니다. 예를 들어, GET이나 POST 메서드를 사용하고, 커스텀 헤더를 피하며, application/x-www-form-urlencoded와 같은 기본적인 Content-Type을 사용합니다.

 

5. 요약

  • CORS 오류는 자바스크립트가 다른 출처의 리소스를 요청할 때 발생하며, 서버가 적절한 CORS 정책을 설정하지 않으면 발생합니다.
  • 문제를 해결하려면 서버에서 올바른 CORS 헤더를 설정하거나, 프록시 서버를 사용하는 등의 방법을 고려해야 합니다.
  • CORS 오류는 보안 메커니즘이므로 서버와 클라이언트 간의 데이터를 안전하게 보호하는 방법입니다.

 

 

728x90