How to make XMLHttpRequest cross-domain using Credentials, HTTP authorization (CORS)?

I cannot complete a cross-domain request with an authorization header (testing using Firefox). I have requests that work without authentication, but as soon as I set withCredentials to true, I can no longer read the response from the server.

On the server, I send these headers (using the after_request method in Flask):

 resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers['Access-Control-Allow-Credentials'] = 'true' resp.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS' resp.headers['Access-Control-Allow-Headers'] = 'Authorization' 

No OPTIONS call is actually made by Firefox. On the client, I call the XMLHttpRequest call:

 var xhr = new XMLHttpRequest() xhr.open( 'POST', 'http://test.local:8002/test/upload', true) xhr.withCredentials = true xhr.onreadystatechange = function() { console.log( xhr.status, xhr.statusText ) } xhr.send(fd) 

Without withCredentials set, the log statement will write pending information to the console. As soon as I set the value, however xhr does not allow access, and I just write the value 0 and an empty string. I did not set an authorization header here, but this should not affect my ability to read the result.

If I try to add the username / password to the "open" command, I get the error NS_ERROR_DOM_BAD_URI: Access to restricted URI denied .

What am I doing wrong?

+17
Feb 18 '14 at 10:12
source share
1 answer

I wrote an article with a complete CORS setup.

I found several problems that may lead to this problem:

  • Access-Control-Allow-Origin cannot be a wildcard if credentials are used. The easiest way is to simply copy the Origin request header into this field. It is not clear why the standard prohibits a template.
  • Firefox caches Access-Control results, even if you clear the cache (possibly for a session). A restart forced him to execute a new OPTIONS request. To help with debugging, I added the Access-Control-Max-Age: 1 header Access-Control-Max-Age: 1
  • The username / password for the open command is apparently not used as credentials. You must add the Authorization header yourself. xhr.setRequestHeader( 'Authorization', 'Basic ' + btoa( user + ':' + pass ) )

The whole system withCredentials is pretty braindead. It’s easier to just write a server that accepts authorization as part of the request body.

+34
Feb 18 '14 at 10:46
source



All Articles