개발을 하다보면 javascript를 이용하여 ajax통신을 할 떄가 있습니다.(jquery를 쓰든 안쓰든) 이럴 때 종종 No Access-Control-Allow-Origin header is...CORS disabled
하며 발생하는 에러를 만나볼 수 있습니다. 이 에러는 무엇이고 어떻게 해결할 수 있는지 알아보도록 하겠습니다.
Security Policy : Same-Origin
웹 사이트는 종종 다른 서버에 요청을 전송하곤 합니다. 서버는 다른 서비스의 요청으로부터 서버를 지키기 위해 보안 정책을 사용합니다. 그 중 하나가 Same-Origin 입니다.
Same-Origin 정책(policy)은 매우 제한적 입니다. 이 정책내에서는 A서버의 문서(Resource)가 A서버의 다른 문서와만 상호작용 할 수 있습니다. 간단히 말하면 같은 서버(Same origin)에서만 문서가 상호작용 할 수 있도록 강제하는 것 입니다. Same-Origin을 판단하는 기준은 Protocol, Port(명시한 경우), Host 입니다. 이 것들이 모두 같아야 Same-Origin이라고 말할 수 있습니다.
예를 들어 다음과 같은 URL이 있다고 하겠습니다.
1
http://www.example.com/index.html
이 URL을 기준으로 다른 요청들에 대해 결과를 확인해 보겠습니다.
URL | 결과 | 이유 |
---|---|---|
http://www.example.com/ex/ex.html | 성공 | 경로만 다름 |
https://www.example.com/index.html | 실패 | Protocol 다름 |
http://www.example2.com/index.html | 실패 | Host 다름 |
http://www.example.com:82/index.html | 실패 | Port 다름 |
위의 테이블에서 볼 수 있듯이 보안에는 문제가 없지만 상당히 제한적인 요청만 받을 수 있습니다.
이를 발전 시켜 나온 것이 CORS 입니다.
CORS(Cross-Origin Resource Sharing)
Origin의 외부에서 Resource를 요청하는 것을 Cross-Origin이라고 합니다. CORS는 이 Cross-Origin을 관리하는 것을 말합니다.
Origin Server 는 CLient의 요청을 처리하고 응답하는 Server 입니다.
Same-Origin 때와는 달리 위의 표의 요청은 성공 할 수 있습니다.(CORS에서) 대신 CORS 표준이 필요합니다. 왜냐하면 CORS를 허용하게 되면 Resource에 접근할 수 있는 요청과 접근 가능한 Resource도 설정할 수 있기 때문입니다.
또한 CORS는 HTTP request Method를 사용하여 만들어 졌고, 대부분의 서버에서는 GET 메소드를 허용할 것 입니다. 그러나 POST, PUT, PATCH, DELETE등은 허용되지 않을 수 있습니다. 왜냐하면 악의적으로 요청을 보내어 Resource를 변화시킬 수 있기 때문입니다.
CORS의 요청관리는 HTTP Header를 통해서 이루어 집니다.
Aceess-Control-Allow-Origin
Aceess-Control-Allow-Credentials
Aceess-Control-Allow-Headers
Aceess-Control-Allow-Methods
Aceess-Control-Expose-Headers
Aceess-Control-Max-Age
Aceess-Control-Request-Headers
Aceess-Control-Request-Method
Origin
모두 중요하지만 Aceess-Control-Allow-Origin
을 보겠습니다. 이 헤더는 Server가 자신의 Resource를 외부 도메인과 공유하는 방법을 지정합니다. 많은 경우 *
을 값으로 지정하며 이 경우 모든 도메인이 공유함을 의미합니다. 원하는 도메인만 설정할 경우 *
값 대신 특정 도메인 리스트를 설정할 수 있습니다.
PRE-FLIGHT REQUESTS
많은 경우 GET
을 제외한 request method는 block되어 있습니다. 그러나 서버는 무조건 적으로 차단하지는 않고 어떤 요청이 허용되는지를 확인한 후 통신하는 프로세스를 갖고 있습니다. 다음 HTTP Request 중 하나를 사용하여 요청이 이루어 지면 기존의 요청 전 Pre-flight 요청이 이루어 집니다.
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
Pre-flight 요청은 대부분 OPTIONS
헤더를 사용합니다. Pre-flight요청의 이름으로도 알 수 있듯 원래의 요청 이전에 전송이 됩니다. 기존의 요청이 안전한지 확인하기 위함이며, 서버가 안전하다고 지정하면 원래의 요청을 허용하고 그렇지 않으면 차단합니다. 아래의 그림은 Pre-flight 요청의 과정을 보여 줍니다.
이 Pre-flight외에도 JSONp와 같이 많은 Resource 공유 솔루션이 있습니다. 그러나 전체적인 개념은 동일 합니다. 이번에는 Same-Origin 과 CORS에 대해 알아봤으며, 다음에는 CORS에 대해 실습해 보겠습니다.
Ref
- https://auth0.com/blog/cors-tutorial-a-guide-to-cross-origin-resource-sharing/
- https://www.codecademy.com/articles/what-is-cors
- https://developer.mozilla.org/ko/docs/Web/HTTP/CORS