소개
일부 ajax 호출이나 React SPA에서 작업 한 적이 있다면 성가신 CORS 오류에 익숙할 것입니다. 이 경우 우리를 위한 해결책으로 가는 것은 백엔드 사람들과 이야기하고 YOLO 때문에 모든 것을 허용하도록 요청하는 것입니다. 그러나 CORS 란 무엇입니까? 프론트 엔드 개발자를 괴롭히는 방법일까요? 보안과 관련이 있습니까? 그렇다면 왜 인증 키와 비밀 키가 필요합니까? 그렇지 않다면 어떤 목적으로 해결됩니까? 처음에는 어떻게 작동합니까?
https://www.arbazsiddiqui.me/cors-understanding-cross-origin-resource-sharing/
이러한 질문이 있으면 이 기사를 참조하십시오. CORS를 처리하는 동안 발생할 수 있는 문제에 대한 해결책을 제안하고 이 모든 것에 대답하려고 시도합니다.
CORS 란 무엇입니까?
CORS (Cross-Origin Resource Sharing)가 무엇인지 이해하려면 먼저 SOP (Same Origin Policy)가 무엇인지 이해해야 합니다.
SOP는 한 최신 버전에서 로드 된 스크립트와 리소스가 다른 원본과 상호 작용할 수 없도록 하는 모든 최신 브라우저에서 구현되는 보안 조치입니다. 즉, www.example.com을 사용하여 웹 사이트를 호스팅 하는 경우 www.test.com에 XHR 요청을 할 수 없습니다. 이것이 어떻게 도움이 됩니까? 이미 페이스 북에 로그인하고 악의적인 웹 사이트를 여는 시나리오를 고려하십시오. 이 웹 사이트는 페이스 북 요청을 하고 로그인 한 세션에서 개인 정보를 추출 할 수 있습니다. 이를 방지하기 위해 SOP는 브라우저에서 구현됩니다. SOP는 서버에 대한 액세스를 제한하지 않으며 API 키 및 비밀 키와 같은 메커니즘을 사용합니다. 실제로 서버는 이 모든 것을 알지 못하고 curl 또는 postman을 사용하여 동일한 요청을 할 수 있으며 작동합니다.
SOP가 교차 원본 액세스를 제한하는 방법 인 경우 CORS는 이를 회피하고 프런트 엔드가 서버에 합법적인 요청을 할 수 있는 방법입니다. 클라이언트가 서버와 다른 출처에서 호스팅 되는 경우 SOP로 인해 클라이언트가 서버에 xhr 요청을 할 수 없습니다. CORS를 사용하면 안전하고 관리 된 방식으로 이를 수행 할 수 있습니다.
MDN 웹 문서에 따르면 :
CORS (Cross-Origin Resource Sharing)는 추가 HTTP 헤더를 사용하여 브라우저가 한 출처에서 실행 중인 웹 응용 프로그램에 다른 출처에서 선택한 리소스에 액세스하도록 지시하는 메커니즘입니다.
origin은 무엇입니까?
우리는 이미 origin이라는 용어를 느슨하게 사용하고 있으며 나머지 기사에서도 계속 사용할 것입니다. 따라서 origin와 관련된 복잡성을 아는 것이 좋습니다. 출처는 구성표 (프로토콜), 호스트 (도메인) 및 포트의 세 부분으로 구성됩니다.
이 세 가지 구성 요소가 모두 같으면 두 개의 origin이 같다고 합니다. 이러한 구성 요소 중 하나가 다른 경우 서로 다릅니다.
예를 들어 http://example.com/app1/index.html 및 http://example.com/app2/index.html은 동일한 출처이므로 http://example.com:80 및 http : // example도 .com (http의 기본 포트는 80입니다).
그러나 프로토콜이 다르기 때문에 http://example.com/app1과 https://example.com/app2는 다른 출처입니다.
마찬가지로 http://example.com과 http://www.example.com은 도메인이 다르기 때문에 다른 출처입니다.
CORS는 어떻게 작동합니까?
CORS 사양을 통해 서버는 클라이언트가 이해하고 이러한 헤더를 기반으로 브라우저가 요청을 제공할지 여부를 결정할 수 있는 응답으로 일부 헤더를 다시 보낼 수 있습니다.
이러한 헤더가 여러 개 있지만 주 헤더는 Access-Control-Allow-Origin입니다. 이 헤더의 값은 * 일 수 있습니다.
이는 서버가 모든 사람이 리소스에 액세스 할 수 있도록 구성되었음을 의미합니다. 또는 허용 된 특정 원점이 될 수 있습니다.
Access-Control-Allow-Origin: https://example.com
CORS 요청에는 "단순"요청과 "프리 플라이트"요청의 두 가지 유형이 있으며 사용되는 유형을 결정하는 브라우저입니다. 개발자는 이 구별을 할 필요는 없지만 이 두 유형이 디버깅 목적으로 어떻게 작동하는지 잘 알고 있습니다.
간단한 요청 :
API 요청이 다음 기준을 모두 충족하는 경우 간단한 요청으로 간주됩니다.
이 두 가지는 간단한 요청 유스 케이스를 대부분 구성하지만 자세한 목록은 여기에서 찾을 수 있습니다.
이제 API 요청이 단순하다고 간주되면 브라우저는 계속 진행하여 서버를 호출하면 서버는 CORS 헤더로 응답합니다. 브라우저는 응답에서 Access-Control-Allow-Origin 헤더를 확인하고 그에 따라 진행합니다.
사전 비행 요청 :
API 호출이 간단한 요청의 기준을 충족하지 않는 경우 (가장 일반적인 내용은 application / json 인 Content-Type 값) 브라우저는 실제 요청을 보내기 전에 요청합니다. 실제 요청을 하기 전에 이 요청을 프리 플라이트 요청이라고 합니다.
비행 전 요청에는 실제 요청의 모든 정보가 포함되며 옵션 OPTIONS로 작성됩니다.
서버는 실제 API 호출에 대한 모든 CORS 헤더를 사용하여 이 프리 플라이트에 응답하므로 브라우저는 실제 API 호출을 수행 할 수 있는지 여부를 알고 있습니다.
예를 들어 https://example.com/status에 GET 호출을 시도하고 있습니다. Content-Type은 application/json이므로 브라우저는 간단한 요청으로 자격을 부여하지 않습니다. 따라서 브라우저는 이 요청을 하기 전에 사전 비행 요청을 합니다.
curl --location --request OPTIONS 'http://example.com/status' \ --header 'Access-Control-Request-Method: GET' \ --header 'Access-Control-Request-Headers: Content-Type, Accept' \ --header 'Origin: http://test.com'
이것은 브라우저에게 서버로 GET 메소드, Content-Type 및 Accept를 헤더로 사용하고 출처 https://test.com에서 호출한다고 알려줍니다. 서버는 이 요청에 다음과 같이 응답합니다.
HTTP/1.1 204 No Content Access-Control-Allow-Origin: * Access-Control-Allow-Methods: OPTIONS, GET, HEAD, POST Access-Control-Allow-Headers: Content-Type, Accept
브라우저가 이를 해석하고 상태 호출이 가능한지 확인합니다. 이 예에서 서버는 원점으로 *로 응답하므로 이제 브라우저는 https://example.com/status 호출을 합니다. 사전 비행 응답에서 출발지가 Access-Control-Allow-Origin : http://domain.com과 같은 것일 경우 Cross-Origin Request Blocked 오류가 발생했을 것입니다.
CORS 오류 처리
우리는 이제 CORS가 무엇이며 어떻게 작동하는지 알고 있습니다. 위에서 주목해야 할 것은 CORS에 대한 완전한 제어가 서버에 있다는 것입니다. 서버 코드에 액세스 할 수 없을 때 나타나는 문제를 어떻게 해결할 수 있습니까? 이러한 시나리오를 하나씩 살펴 보겠습니다.
서버 개발시 CORS
서버를 구축 중이고 일부 클라이언트를 서비스하려는 경우 클라이언트가 요청을 보내는 모든 출처를 허용해야 합니다. 응답으로 하나의 오리진 만 보낼 수 있지만 서버에서 오리진 화이트리스트를 유지하고 요청 된 오리진을 헤더로 다시 보낼 수 있습니다. 노드에서 이를 수행하는 방법은 다음과 같습니다.
app.use(function(req, res, next) { const allowedOrigins = ['http://127.0.0.1:8020', 'http://localhost:8020', 'http://127.0.0.1:9000', 'http://localhost:9000']; const origin = req.headers.origin; if(allowedOrigins.indexOf(origin) > -1){ res.setHeader('Access-Control-Allow-Origin', origin); } res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.header('Access-Control-Allow-Credentials', true); return next(); });
가장자리에 살고 싶다면 Access-Control-Allow-Origin : *을 사용하여 모든 출처가 서버에 요청하도록 할 수 있습니다.
클라이언트 개발시 CORS
서버를 제어 할 수 없는 경우, 즉 타사 호출을 하고 개발자에게 연락하여 출처를 추가 할 수 없는 경우입니다. 이 타사에 XHR 요청을 할 수 없으므로 까다로운 상황입니다. 이 경우 서버 자체를 변경하려고 할 수 있습니다. 즉, 출발지를 허용하는 프록시 서버를 만든 다음 해당 프록시 서버가 타사 호출을 수행합니다. 앞에서 언급했듯이 서버는 SOP를 이해하지 못하므로 프록시 서버는 우편 배달부와 같은 다른 클라이언트와 같은 문제 없이 타사 서버를 호출 할 수 있습니다. 프록시 서버를 생성하고 이 프록시 서버에서 올바른 CORS 헤더를 전송하기 만하면 됩니다. core-anywhere와 같이 이 사용 사례에 대한 준비된 솔루션이 있습니다.
결론
우리는 SOP가 무엇이며 CORS가 SOP에 의해 부과 된 제한을 우회 하는 데 어떻게 사용 되는지에 대해 배웠습니다. 또한 브라우저 및 API와 함께 제공되는 헤더를 통해 API가 CORS를 처리하는 다양한 방법을 살펴 보았습니다.
마지막으로 애플리케이션 개발시 Cross-Origin Request Blocked 오류를 처리하기 위한 시나리오와 솔루션을 살펴 보았습니다.
등록된 댓글이 없습니다.