I'm unable to make a cross-domain request with an Authorization header (testing with Firefox). I have requests working without authentication, but once I set withCredentials
to true I am no longer able to read the response from the server.
On the server I send back these headers (using an 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 ever actually made by Firefox. On the client I make an 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 log the expecting information to the console. Once I set the value however the xhr doesn't allow access and I just write a 0 value and an empty string. I haven't set the authorization header here, but that shouldn't affect my ability to read the result.
If I attempt to add a username/password to the "open" command I get a NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
error.
What am I doing wrong?
I've written an article with a complete CORS setup.
I found several issues that can result in this problem:
Access-Control-Allow-Origin
cannot be a wildcard if credentials are being used. It's easiest just to copy theOrigin
header of the request to this field. It's entirely unclear why the standard would disallow a wildcard.OPTIONS
request. To aid in debugging I added the headerAccess-Control-Max-Age: 1
open
command is apparently not usable as the credentials. You must add anAuthorization
header yourself.xhr.setRequestHeader( 'Authorization', 'Basic ' + btoa( user + ':' + pass ) )
Overall the
withCredentials
system is rather braindead. It's easier to simply write a server that accepts the authorization as part of the body of the request.