Reputation: 10226
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.
Upvotes: 3
Views: 3215
Reputation: 10226
Additionally to the working CORS configuration and htaccess setup:
SetEnvIfNoCase Request_Method OPTIONS noauth
Order Deny,Allow
Deny from all
Require valid-user
Allow from env=noauth
Satisfy Any
you have to make sure that your ajax setup does not have the withCredentials
and password
and username
, like in my question. This leads to errors in Firefox, at least. Working ajax:
$.ajaxSetup({
xhrField: {
withCredentials : true
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic foobarbarfoo');
}
});
request = $.ajax({
url: isApiActive ? apiBaseUrl + 'api/mydata' : './mydata.json',
dataType: 'json',
type: 'get'
});
Upvotes: 1
Reputation: 88235
Response is 401 "Authorization required", it says request method is OPTIONS (?).
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 the Authorization
request header.
So what’s happening is:
Authorization
header.Authorization
header require me to do a CORS preflight OPTIONS
to make sure the server allows requests with the Authorization
header.OPTIONS
request to the server without the Authorization
header, because the whole purpose of the OPTIONS
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 the Authorization
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 handles OPTIONS
requests without authorization being required.
Once you fix that, the existing cors.config
shown in the question should cause the server to respond to the OPTIONS
request in the right way—with an Access-Control-Allow-Headers
response header that includes Authorization
, so that your browser can then say, OK, this server allows cross-origin requests that contain the Authorization
header, so I’ll now go ahead and send the actual GET
request.
Upvotes: 2