问题
I'm stuck trying to diagnose a problem where a GET request with HTTP Basic Auth succeeds in Node, but fails in the browser. The problem manifests directly as a CORS failure (there's no Access-Control-Allow-Origin on the 401 page).
request.js:119 OPTIONS http://HOST?PARAMS 401 (Unauthorized)
ClientRequest._onFinish @ request.js:119
(anonymous) @ request.js:61
...
17:53:59.170 localhost/:1 Failed to load http://HOST?PARAMS: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9966' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The request looks like this:
const request = require("request-promise");
const options = {"url":"http://...?","auth":{"user":"...","pass":"..."},"json":true,"qs":{...},"headers":{},"resolveWithFullResponse":true}
request.get(options).then(...);
How this request shows up in Chrome:
What's surprising here to me:
- The method is OPTIONS, not GET. (Which I didn't explicitly ask for.)
- My auth credentials are not included in the headers (even though I haven't set
sendImmediately: false
- The "Provisional headers are shown" warning.
What I would like to know:
- Is this expected behaviour?
- If not, what's going wrong?
- If yes, what's going wrong? :)
Running what would be the equivalent request on the command line seems to work fine:
curl -I 'http://MYUSERNAME:MYPASSWORD@SAMEURL?SAME=PARAMETERS' -H 'Origin: http://localhost:4466' -X OPTIONS
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2018 07:29:28 GMT
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:4466
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Vary: Origin
X-Frame-Options: SAMEORIGIN
Allow: GET,HEAD,POST,OPTIONS
Content-Length: 0
However I notice that without the credentials supplied in the URL, there are no CORS headers on the response:
HTTP/1.1 401 Unauthorized
Date: Wed, 20 Jun 2018 07:45:26 GMT
Server: Apache/2.4.29 (Unix) OpenSSL/1.0.2l
WWW-Authenticate: Basic realm="Authentication Required"
Content-Length: 381
Content-Type: text/html; charset=iso-8859-1
Is that the correct behaviour?
Hypothesis
I suspect:
- The browser is sending the OPTIONS "pre-flight" request because it has to, because the request is not a "simple request". (Not totally clear if this is the request library or the browser itself doing this)
- The server is responding 401 because credentials weren't supplied, but isn't adding the CORS headers that it should.
- Without the CORS headers the browser prevents the Request library accessing the result, so it can't complete the authentication.
What I'm not sure about:
- Is the server misconfigured?
- Is Request failing to pass credentials in the OPTIONS preflight request?
回答1:
The server is misconfigured. It’s not properly CORS-enabled. To be properly CORS-enabled it must respond to unauthenticated OPTIONS
requests with a 200
or 204
status code.
Request
isn’t “failing” to pass credentials in the OPTIONS
preflight request. Request
isn’t even making the the OPTIONS
request. Instead the browser engine is, on its own.
And specifying the credentials flag for the request in your own code doesn’t cause credentials to get added to the preflight OPTIONS
request. Instead, credentials only get added to the GET
request from your own code — that is, if the preflight has succeeded and the browser actually ever moves on to making that GET
request.
That’s because the CORS-protocol requirements in the Fetch specify that browsers must omit all credentials from preflight OPTIONS
requests.
See https://fetch.spec.whatwg.org/#ref-for-credentials%E2%91%A5:
a CORS-preflight request never includes credentials
So the behavior you’ve encountered is intentional, by design.
For a related explanation in more detail, see the answer at HTTP status code 401 even though I’m sending an Authorization request header.
来源:https://stackoverflow.com/questions/50942883/http-auth-request-fails-in-browser-due-to-cors-ok-in-node