[javascript] Access-Control-Allow-Origin 헤더는 어떻게 작동합니까?

분명히 나는 ​​그 의미를 완전히 오해했습니다. 나는 이와 같은 것을 생각했다.

  1. 에서 클라이언트 다운로드 자바 스크립트 코드 MyCode.js http://siteA기원 .
  2. MyCode.js의 응답 헤더에는 Access-Control-Allow-Origin :이 포함http://siteB 되어 있는데, 이는 MyCode.js가 사이트 B에 대한 출처 간 참조를 허용 할 수 있다고 생각했습니다.
  3. 클라이언트는 MyCode.js의 일부 기능을 트리거합니다.이 기능은에 대한 요청을 수행합니다 http://siteB. 이는 원본 간 요청에도 불구하고 괜찮습니다.

글쎄, 나는 틀렸다. 이처럼 전혀 작동하지 않습니다. 따라서 출처 간 리소스 공유 를 읽었 으며 w3c 권장 사항에서 출처 간 리소스 공유 를 읽으려고했습니다.

한 가지 확실한 점은 여전히이 헤더를 어떻게 사용 해야하는지 이해하지 못하는 것입니다.

사이트 A와 사이트 B를 완전히 제어 할 수 있습니다. 사이트 A에서 다운로드 한 자바 스크립트 코드를 사용하여이 헤더를 사용하여 사이트 B의 리소스에 액세스하려면 어떻게해야합니까?

추신

JSONP를 사용하고 싶지 않습니다.



답변

Access-Control-Allow-OriginA는 CORS (교차 리소스 공유) 헤더 .

사이트 A가 사이트 B에서 콘텐츠를 가져 오려고하면 사이트 B는 Access-Control-Allow-Origin응답 헤더를 보내서 브라우저에이 페이지의 콘텐츠를 특정 출처에서 액세스 할 수 있음을 알릴 수 있습니다. ( 원점도메인과 구성표 및 포트 번호를 더한 것 입니다.) 기본적으로 사이트 B의 페이지는 다른 원본에 액세스 할 수 없습니다 . Access-Control-Allow-Origin헤더를 사용하면 특정 요청 원점으로 교차 출처 액세스를위한 문이 열립니다.

사이트 B가 사이트 A에 액세스 할 수 있도록하려는 각 리소스 / 페이지에 대해 사이트 B는 응답 헤더와 함께 해당 페이지를 제공해야합니다.

Access-Control-Allow-Origin: http://siteA.com

최신 브라우저는 도메인 간 요청을 완전히 차단하지 않습니다. 사이트 A가 사이트 B에서 페이지를 요청하면 브라우저는 실제로 네트워크 수준 에서 요청 된 페이지 가져오고 응답 헤더가 사이트 A를 허용 된 요청자 도메인으로 나열하는지 확인합니다. 사이트 B가 사이트 A가이 페이지에 액세스 할 수 있다고 표시하지 않으면 브라우저는 XMLHttpRequesterror이벤트를 트리거 하고 요청하는 JavaScript 코드에 대한 응답 데이터를 거부합니다.

단순하지 않은 요청

네트워크 수준에서 발생하는 상황은 위에서 설명한 것보다 약간 더 복잡 할 수 있습니다 . 요청이 “단순하지 않은”요청 인 경우, 브라우저는 먼저 데이터가없는 “프리 플라이트”OPTIONS 요청을 전송하여 서버가 요청을 수락하는지 확인합니다. 다음 중 하나 또는 둘 모두의 경우 요청이 단순하지 않습니다.

  • GET 또는 POST 이외의 HTTP 동사 사용 (예 : PUT, DELETE)
  • 단순하지 않은 요청 헤더 사용 유일한 간단한 요청 헤더는 다음과 같습니다.
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(이 값은 단순한 경우이다 application/x-www-form-urlencoded, multipart/form-data또는 text/plain)

서버 Access-Control-Allow-Headers가 단순 Access-Control-Allow-Methods하지 않은 동사 및 / 또는 단순하지 않은 헤더와 일치하는 적절한 응답 헤더 ( 단순하지 않은 헤더, 단순 하지 않은 동사의 경우) 를 사용하여 OPTIONS 프리 플라이트에 응답 하면 브라우저는 실제 요청을 보냅니다.

사이트 A가 /somePage단순 Content-Type값이 아닌에 대한 PUT 요청을 보내려고한다고 가정하면 application/json브라우저는 먼저 프리 플라이트 요청을 보냅니다.

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

그 주 Access-Control-Request-MethodAccess-Control-Request-Headers브라우저에 의해 자동으로 추가됩니다; 추가하지 않아도됩니다. 이 옵션 프리 플라이트는 성공적인 응답 헤더를 얻습니다.

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

실제 요청을 전송할 때 (사전 비행 완료 후), 동작은 간단한 요청이 처리되는 방식과 동일합니다. 다시 말해, 프리 플라이트가 성공한 단순하지 않은 요청은 단순 요청과 동일하게 처리됩니다 (즉, Access-Control-Allow-Origin실제 응답을 위해 서버가 여전히 다시 전송해야 함 ).

브라우저는 실제 요청을 보냅니다.

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

그리고 서버는 Access-Control-Allow-Origin간단한 요청과 마찬가지로을 다시 보냅니다 .

Access-Control-Allow-Origin: http://siteA.com

단순하지 않은 요청에 대한 자세한 내용은 CORS통한 XMLHttpRequest 이해를 참조하십시오 .


답변

Cross-Origin Resource Sharing- CORS(AKA Cross-Domain AJAX 요청)은 대부분의 웹 개발자가 겪는 문제입니다. Same-Origin-Policy에 따르면 브라우저는 보안 샌드 박스에서 클라이언트 JavaScript를 제한합니다. 일반적으로 JS는 원격 서버와 직접 통신 할 수 없습니다 다른 도메인에서 과거 개발자들은 도메인 간 리소스 요청을 달성하기 위해 많은 까다로운 방법을 만들었습니다. 가장 일반적으로 사용되는 방법은 다음과 같습니다.

  1. Flash / Silverlight 또는 서버 측을 “프록시”로 사용하여 원격과 통신하십시오.
  2. 패딩이있는 JSON ( JSONP ).
  3. 원격 서버를 iframe에 내장하고 조각 또는 window.name을 통해 통신합니다 ( 여기 참조) .

이러한 까다로운 방법에는 다소 문제가 있습니다. 예를 들어 JSONP는 개발자가 단순히 “평가”하는 경우 보안 허점을 초래할 수 있으며 위의 # 3은 작동하지만 두 도메인은 서로간에 엄격한 계약을 구축해야합니다. 이모 🙂

W3C는이 문제를 해결하기 위해 안전하고 유연하며 권장되는 표준 방법을 제공하기 위해 표준 솔루션으로 CORS (Cross-Origin Resource Sharing)를 도입했습니다.

메커니즘

높은 수준에서 간단히 CORS는 도메인 A의 클라이언트 AJAX 호출과 도메인 B에서 호스팅 된 페이지 간의 계약으로 간주됩니다. 일반적인 Cross-Origin 요청 / 응답은 다음과 같습니다.

DomainA AJAX 요청 헤더

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

DomainB 응답 헤더

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

위에 표시된 파란색 부분은 “원본”요청 헤더 “원점 간 요청 또는 프리 플라이트 요청의 출처”를 나타내는 핵심 사실입니다. “Access-Control-Allow-Origin”응답 헤더는이 페이지가 원격 요청을 허용 함을 나타냅니다. DomainA (값이 * 인 경우 모든 도메인의 원격 요청을 허용 함).

위에서 언급했듯이 W3 는 실제로 Cross-Origin HTTP 요청을 제출하기 전에 ” 프리 플라이트 요청 ” 을 구현하도록 브라우저를 권장 했습니다. 간단히 말해서 HTTP OPTIONS요청입니다.

OPTIONS DomainB.com/foo.aspx HTTP/1.1

foo.aspx가 OPTIONS HTTP 동사를 지원하면 아래와 같은 응답을 반환 할 수 있습니다.

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

응답에 “Access-Control-Allow-Origin”이 포함되고 값이 “*”이거나 CORS 요청을 제출 한 도메인을 포함하는 경우에만이 필수 조건을 만족하여 브라우저가 실제 도메인 간 요청을 제출하고 결과를 캐시합니다. ” 사전 비행 결과 캐시

3 년 전에 CORS에 대해 블로그했습니다 : AJAX Cross-Origin HTTP 요청


답변

질문에 대답하기에는 너무 오래되었지만 나중에이 질문에 대한 참조를 위해 이것을 게시하고 있습니다.

Mozilla 개발자 네트워크 기사 에 따르면

자원은 첫 번째 자원 자체가 제공하는 것과 다른 도메인이나 포트에서 자원을 요청할원본 간 HTTP 요청을 합니다.

여기에 이미지 설명을 입력하십시오

HTML 페이지 에서 제공은 http://domain-a.com<img>에 대한 SRC 요청을 http://domain-b.com/image.jpg.
오늘날 웹상의 많은 페이지는 CSS 스타일 시트 , 이미지스크립트 와 같은 리소스 를 별도의 도메인에서 로드 합니다 (따라서 멋지다).

동일 출처 정책

보안상의 이유로 브라우저 는 스크립트 내에서 시작된 출처 간 HTTP 요청을 제한 합니다 .
예를 들어, 및 후속 동일 출처 정책을 .
따라서 웹 애플리케이션을 사용 하거나 자체 도메인대한 HTTP 요청 만 할 수 있습니다 .
XMLHttpRequestFetch
XMLHttpRequestFetch

CORS (Cross-Origin Resource Sharing)

웹 애플리케이션을 개선하기 위해 개발자는 브라우저 공급 업체에 도메인 간 요청을 허용하도록 요청했습니다.

간 리소스 공유 (CORS) 메커니즘은 웹 서버를 제공합니다 크로스 도메인 액세스 제어 보안 도메인 간 데이터 전송을 가능하게.
최신 브라우저 는 API 컨테이너 에서 CORS 를 사용 하여 ( 예 : 또는) 원본 간 HTTP 요청의 위험을 완화합니다.XMLHttpRequestFetch

CORS 작동 방식 ( Access-Control-Allow-Origin헤더)

위키 백과 :

CORS 표준은 브라우저와 서버에 권한이있는 경우에만 원격 URL을 요청할 수있는 방법을 제공하는 새로운 HTTP 헤더를 설명합니다.

일부 유효성 검사 및 권한 부여는 서버에서 수행 할 수 있지만 일반적으로 이러한 헤더를 지원하고 해당 제한을 적용하는 것은 브라우저의 책임 입니다.

  1. 브라우저는 OPTIONS요청을 Origin HTTP헤더 와 함께 보냅니다 .

    이 헤더의 값은 상위 페이지를 제공 한 도메인입니다. 의 페이지가에서 http://www.example.com사용자의 데이터에 액세스하려고 service.example.com하면 다음 요청 헤더가로 전송됩니다 service.example.com.

    출처 : http://www.example.com

  2. 의 서버는 다음 service.example.com과 같이 응답 할 수 있습니다.

    • Access-Control-Allow-Origin어떤 오리진 사이트가 허용되는지를 나타내는 응답 의 (ACAO) 헤더.
      예를 들면 다음과 같습니다.

      Access-Control-Allow-Origin: http://www.example.com

    • 서버가 교차 출처 요청을 허용하지 않는 경우 오류 페이지

    • Access-Control-Allow-Origin모든 도메인을 허용하는 와일드 카드가 있는 (ACAO) 헤더 :

      Access-Control-Allow-Origin: *


답변

CORS에 대해 생각하기 시작할 때마다 질문에 설명 된 것처럼 헤더를 호스팅하는 사이트에 대한 내 직감이 잘못되었습니다. 저에게는 동일한 원산지 정책의 목적에 대해 생각하는 것이 도움이됩니다.

동일한 출처 정책의 목적은 siteB.com 과만 공유하도록 선택한 개인 정보에 액세스하는 siteA.com의 악성 JavaScript로부터 사용자를 보호하는 것입니다. 동일한 출처 정책이 없으면 siteA.com의 작성자가 작성한 JavaScript는 siteB.com의 인증 쿠키를 사용하여 브라우저가 siteB.com에 요청을 할 수 있습니다. 이런 식으로 siteA.com은 siteB.com과 공유하는 비밀 정보를 훔칠 수 있습니다.

때로는 CORS가 제공되는 도메인 간 작업이 필요합니다. CORS는 domainA Access-Control-Allow-Origin와 상호 작용할 수있는 JavaScript를 실행하도록 신뢰할 수있는 다른 도메인 (domainA.com)을 나열하기 위해 헤더를 사용하여 domainB.com에 대한 동일한 원본 정책을 완화합니다 . com.

CORS 헤더를 제공해야하는 도메인을 이해하려면이를 고려하십시오. mybank.com에 대한 도메인 간 요청을 시도하는 JavaScript가 포함 된 malicious.com을 방문합니다. 악성 .com의 JavaScript가 상호 작용할 수 있도록 동일한 오리진 정책을 완화하는 CORS 헤더를 설정할지 여부를 결정하는 것은 악성 .com이 아닌 mybank.com의 책임입니다. malicous.com이 mybank.com에 대한 자체 JavaScript 액세스를 허용하는 자체 CORS 헤더를 설정할 수 있으면 동일한 원본 정책이 완전히 무효화됩니다.

내 직관이 잘못된 이유는 사이트를 개발할 때 내가 생각하는 관점이라고 생각합니다. 그건 모두와 사이트 따라서 악성 아무것도하지 않는, 자바 스크립트, 그것은까지해야 다른 어떤 사이트 지정 자바 스크립트와 상호 작용할 수 있습니다. 사실 JavaScript가 내 사이트와 상호 작용하려고 하는 다른 사이트를 생각하고 CORS를 사용하여 사이트를 허용해야합니까?


답변

1. 클라이언트가 http : // siteA-원본에서 javascript 코드 MyCode.js를 다운로드 합니다.

다운로드를 수행하는 코드-html 스크립트 태그 또는 javascript의 xhr 또는 그 밖의 모든 것-http : // siteZ 라고 가정 해 봅시다 . 그리고 브라우저가 MyCode.js를 요청하면 siteA 및 siteZ! = siteA에 요청하고 있음을 알 수 있으므로 ” Origin : http : // siteZ ” 라는 Origin : 헤더를 보냅니다 . (중지하거나 방해 할 수 없습니다.)

2. MyCode.js의 응답 헤더에는 Access-Control-Allow-Origin : http : // siteB가 포함 되어 있는데, 이는 MyCode.js가 사이트 B에 대한 출처 간 참조를 허용 한 것으로 생각했습니다.

아니. 즉, siteB 만이 요청을 수행 할 수 있습니다. 따라서 siteZ에서 MyCode.js를 요청하면 오류가 발생하고 브라우저는 일반적으로 아무것도 제공하지 않습니다. 그러나 서버가 ACAO : siteZ를 반환하게하면 MyCode.js가됩니다. 또는 ‘*’를 보내면 작동합니다. 모두가 들어올 수 있습니다. 또는 서버가 항상 Origin : 헤더에서 문자열을 보내면 … 보안을 위해 해커를 두려워하는 경우 , 서버는 해당 요청을 할 수있는 후보 목록의 원본 만 허용해야합니다.

그런 다음 MyCode.js는 siteA에서 제공됩니다. 사이트 B에 요청하면 모두 교차 출처이며 브라우저는 Origin : siteA를 보내며 siteB는 siteA를 가져 와서 허용 된 요청자의 짧은 목록에 있음을 인식하고 ACAO : siteA를 다시 보냅니다. 그래야만 브라우저에서 스크립트가 해당 요청의 결과를 얻을 수 있습니다.


답변

ReactAxios를 사용하여 프록시 링크를 URL에 연결하고 아래와 같이 헤더를 추가하십시오.

https://cors-anywhere.herokuapp.com/ + Your API URL

프록시 링크를 추가하는 것만으로도 작동하지만 No Access에 대한 오류가 다시 발생할 수 있습니다. 따라서 아래와 같이 헤더를 추가하는 것이 좋습니다.

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }


답변

브라우저가 요청을 차단하는 교차 도메인 응용 프로그램을 테스트하려는 경우 브라우저를 안전하지 않은 모드로 열고 코드를 변경하지 않고 코드를 안전하지 않은 상태로 응용 프로그램을 테스트하면됩니다. MAC OS에서는 터미널 라인에서 다음을 수행 할 수 있습니다.

open -a Google\ Chrome --args --disable-web-security --user-data-dir