Since Drupal 8.2 the cors setup is in core. In my services.yml
(and default.services.yml
) I have the following setup:
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['*']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: false
# Sets the Access-Control-Max-Age header.
maxAge: 1000
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: true
My domain a.com
is htaccess password protected.
On domain b.com
I try to load some API from domain a.com
:
$.ajaxSetup({
xhrField: {
withCredentials : true
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic Z2VuaXVzOmNvYXRpbmdz');
}
});
request = $.ajax({
url: apiBaseUrl + 'api/foobar',
dataType: 'json',
type: 'get',
password: 'foo',
username: 'bar'
});
In chrome it works fine, in firefox I get an error. The request headers:
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Response is 401 "Authorization required", it says request method is OPTIONS (?).
Whats wrong here?
Doing the same request in insomnia works perfectly fine.
Additionally to the working CORS configuration and htaccess setup:
you have to make sure that your ajax setup does not have the
withCredentials
andpassword
andusername
, like in my question. This leads to errors in Firefox, at least. Working ajax:You need to configure your server backend to not require authorization for
OPTIONS
requests.That 401 response indicates the server is requiring authorization for an
OPTIONS
request, but authorization is failing because the request doesn’t contain the required credentials.The reason is, that
OPTIONS
request is sent automatically by your browser as part of CORS.https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests explains in general why browsers make CORS preflight
OPTIONS
requests, but in the specific case in the question, the reason is because the request contains theAuthorization
request header.So what’s happening is:
Authorization
header.Authorization
header require me to do a CORS preflightOPTIONS
to make sure the server allows requests with theAuthorization
header.OPTIONS
request to the server without theAuthorization
header, because the whole purpose of theOPTIONS
check is to see if it’s OK to include that header.OPTIONS
request but instead of responding to it in a way that indicates it allows theAuthorization
header in requests, it rejects it with a 401 since it lacks the header.GET
request from your code.So you need to figure out what part of your current server-side code is causing your server to require authorization for
OPTIONS
requests, and you need to change that so that it instead handlesOPTIONS
requests without authorization being required.Once you fix that, the existing
cors.config
shown in the question should cause the server to respond to theOPTIONS
request in the right way—with anAccess-Control-Allow-Headers
response header that includesAuthorization
, so that your browser can then say, OK, this server allows cross-origin requests that contain theAuthorization
header, so I’ll now go ahead and send the actualGET
request.