💡 Quotation

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 브라우저가 자신의 출처가 아닌 다른 어떤 출처(도메인, 스킴 혹은 포트)로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 HTTP 헤더 기반 메커니즘입니다. - MDN

WebGL 프로젝트 개발 중 CORS 오류가 저를 너무 힘들게 해서 그 과정과 해결 방법을 공유하려고 글을 쓰게 되었습니다. 😭

우선 왜 이런 오류가 발생하는지 원인부터 제대로 알아보도록 하겠습니다.

원인

✅ 자신의 출처가 아닌 다른 어떤 출처(도메인, 스킴 혹은 포트)로부터 자원을 로딩

원인은 출처가 다른 곳의 리소스를 불러와서 오류가 걸리는 것 입니다!

CORS

클라이언트가 서버로부터 어떤 정보를 요청하려면 먼저 해당 서버의 주소를 먼저 알아야 할겁니다. 대표적으로 URL이 되겠죠?

https://example.com 에 접속했다고 가정을 한다면, RFC 6454 문서에 따라 모든 리소스는 https://example.com에서부터 받아야 합니다.

⚠️ example.com 같은 곳에서 불러왔는데도 CORS 오류가 나옵니다.

도메인이 같더라도 출처가 다를 수 있습니다. 도메인, 프로토콜, 포트를 묶어 하나의 출처가 됩니다. 👍

CORS 동작

순서방법내용비고
0GEThttps://example.com웹 페이지에 접속 OK
1OPTIONShttps://example.com
http://api.example.com:3000
출처 정보 요청
2GEThttp://api.example.com:3000
https://example.com
OK
3GEThttps://example.com
http://api.example.com:3000
리소스 요청
2GEThttp://api.example.com:3000
https://example.com
OK

다른 출처에서 요청한 곳의 출처를 확인한 후 서버 설정에 따라 전달할지 말지 결정됩니다.

여기서 헷갈리지 말아야 할 것은 출처(Origin) 체크를 하기 위해 API 서버에 허용된 도메인을 요청 한다는 점입니다! 따라서 API 서버에서 CORS 관련 설정을 해줄 필요가 있습니다. 이제 CORS가 어떻게 동작하는지, 어떻게 해결해야 하는지 알았습니다.

✅ 결국 브라우저(클라이언트)가 동일 출처 자원 공유인지 체크

해결

HTTP-Header 에 CORS 관련한 내용이 담겨 정보를 주고 받습니다. API 서버에서는 본인이 허락한 출처를 다시 전달할 수 있도록 헤더에 작성해 주기만 하면 됩니다! 😎

제가 사용하고 있는 웹 서버는 nginx 이며 reverse proxy 를 구성해서 ASP.NET core 프로젝트로 연결해서 사용하고 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
	location ~ / {
		if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
            add_header 'Access-Control-Allow-Credentials' 'true';
            return 204;
        }

		proxy_pass http://api.example.com;
		...
	}

2: method 가 OPTIONS 일 경우 (preflight) 3: HTTP-header에 Access-Control-Allow-Origin를 * 로 추가합니다. (모든 출처 허용)

result

모든 출처를 허용한 후 다른 출처에서 잘 불러오는 것을 확인했습니다. 👍