인증 된 CORS 요청의 프리 플라이트 OPTIONS 요청이 Chrome에서는 작동하지만 Firefox에서는 작동하지 않는 이유는 무엇입니까?
제 3 자 사이트에 포함될 JavaScript 클라이언트를 작성 중입니다 (Facebook 좋아요 버튼). 기본 HTTP 인증이 필요한 API에서 정보를 검색해야합니다. 단순화 된 설정은 다음과 같습니다.
타사 사이트의 페이지에 다음 스 니펫이 포함되어 있습니다.
<script
async="true"
id="web-dev-widget"
data-public-key="pUbl1c_ap1k3y"
src="http://web.dev/widget.js">
</script>
widget.js 는 API를 호출합니다.
var el = document.getElementById('web-dev-widget'),
user = 'token',
pass = el.getAttribute('data-public-key'),
url = 'https://api.dev/',
httpRequest = new XMLHttpRequest(),
handler = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
console.log('There was a problem with the request.', httpRequest);
}
}
};
httpRequest.open('GET', url, true, user, pass);
httpRequest.onreadystatechange = handler;
httpRequest.withCredentials = true;
httpRequest.send();
API는 적절한 헤더로 응답하도록 구성되었습니다.
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Methods: "GET, OPTIONS"
Header set Access-Control-Allow-Headers: "origin, authorization, accept"
SetEnvIf Origin "http(s)?://(.+?\.[a-z]{3})$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
이 있습니다 Access-Control-Allow-Origin
로 설정되어 Origin
나는 자격을 요청을 전송하고 있기 때문에 대신 와일드 카드를 사용하는 ( withCredentials
).
이제 비동기 교차 도메인 인증 요청을 만들기위한 모든 것이 준비되었으며 OS X 10.8.2의 Chrome 25에서 훌륭하게 작동합니다. Dev Tools에서 OPTIONS
요청 전에 요청에 대한 네트워크 요청을 볼 수 GET
있으며 응답이 예상대로 돌아옵니다.
Firefox 19에서 테스트 할 때 API에 대한 Firebug에 네트워크 요청이 나타나지 않으며이 오류가 콘솔에 기록됩니다. NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
많은 파고 끝에 Gecko가 사용자 이름과 암호가 의견에 따라 교차 사이트 URI 에 직접 들어가는 것을 허용하지 않는다는 것을 발견했습니다 . 나는 이것이 선택적 사용자 및 암호 매개 변수를 사용하는 것으로 가정 open()
했기 때문에 Base64가 자격 증명을 인코딩하고 Authorization 헤더를 보내는 인증 된 요청을 만드는 다른 방법을 시도했습니다.
// Base64 from http://www.webtoolkit.info/javascript-base64.html
auth = "Basic " + Base64.encode(user + ":" + pass);
...
// after open() and before send()
httpRequest.setRequestHeader('Authorization', auth);
This results in a 401 Unauthorized
response to the OPTIONS
request which lead to Google searches like, "Why does this work in Chrome and not Firefox!?" That's when I knew I was in trouble.
Why does it work in Chrome and not Firefox? How can I get the OPTIONS
request to send and respond consistently?
Why does it work in Chrome and not Firefox?
The W3 spec for CORS preflight requests clearly states that user credentials should be excluded. There is a bug in Chrome and WebKit where OPTIONS
requests returning a status of 401 still send the subsequent request.
Firefox has a related bug filed that ends with a link to the W3 public webapps mailing list asking for the CORS spec to be changed to allow authentication headers to be sent on the OPTIONS
request at the benefit of IIS users. Basically, they are waiting for those servers to be obsoleted.
How can I get the OPTIONS
request to send and respond consistently?
Simply have the server (API in this example) respond to OPTIONS
requests without requiring authentication.
Kinvey did a good job expanding on this while also linking to an issue of the Twitter API outlining the catch-22 problem of this exact scenario interestingly a couple weeks before any of the browser issues were filed.
This is an old post but maybe this could help people to complete the CORS problem. To complete the basic authorization problem you should avoid authorization for OPTIONS requests in your server. This is an Apache configuration example. Just add something like this in your VirtualHost or Location.
<LimitExcept OPTIONS>
AuthType Basic
AuthName <AUTH_NAME>
Require valid-user
AuthUserFile <FILE_PATH>
</LimitExcept>
It was particular for me. I am sending a header named 'SESSIONHASH'. No problem for Chrome and Opera, but Firefox also wants this header in the list "Access-Control-Allow-Headers". Otherwise, Firefox will throw the CORS error.
'IT Share you' 카테고리의 다른 글
트위터 부트 스트랩을 만드는 방법 (0) | 2020.12.07 |
---|---|
facet_wrap 레이블을 완전히 제거하십시오. (0) | 2020.12.07 |
문자열을 JSON 객체 PHP로 변환 (0) | 2020.12.07 |
chart.js (chartjs.org)의 모든 차트 유형에 레이블 / 범례를 추가하려면 어떻게해야합니까? (0) | 2020.12.07 |
여러 in 연산자를 사용하는 crudrepository findBy 메서드 서명? (0) | 2020.12.07 |