Why is my Drupal 8 CORS program not working?

Since Drupal 8.2, the cors installation is in the core. In my services.yml

(s 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 password protected by htaccess.

On a domain b.com

I am trying to load some API from a 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. Request headers:

Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization

      

A 401 response "Authorization required", it says the request method is OPTIONS (?).

What's wrong here?

Doing the same query in insomnia works great.

+3


source to share


2 answers


A 401 response "Authorization required", it says the request method is OPTIONS (?).

You need to set up a backend server to not require authorization for requests OPTIONS

.

This 401 response indicates that the server needs authorization for the request OPTIONS

, but authorization fails because the request does not contain the required credentials.

This is because the request is OPTIONS

sent automatically by your browser as part of CORS.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests explains why browsers make CORS preflight requests OPTIONS

, but in the specific case in question the reason is because the request contains a request header Authorization

.



So what's going on:

  • Your codes telling your browser want to send a request with a header Authorization

    .
  • Your browser says "OK, header requests Authorization

    require me to do a CORS preview OPTIONS

    for the server to allow header requests Authorization

    ."
  • Your browser is sending a request to the OPTIONS

    server without a headerAuthorization

    , since the whole purpose of validation OPTIONS

    is to see if it's OK to include that header.
  • Your server sees the request OPTIONS

    , but instead of responding to it with a header Authorization

    in the requests, it rejects it with a 401 because it is missing a header.
  • Your browser expects a 200 or 204 response for CORS preflight, but instead gets a 401 response. This way your browser stops right there and never tries the request GET

    from your code.

So, you need to figure out what part of your current server-side code is causing your server to request authorization for requests OPTIONS

, and you need to change that to handle requests OPTIONS

without the need for authorization instead .

Once you fix this, the existing cors.config

one listed in the question should force the server to respond to the request in the OPTIONS

correct way - with a response header Access-Control-Allow-Headers

that includes Authorization

, so your browser can say "OK", this server allows cross-origin requests containing the header Authorization

. so now I go and post the actual request GET

.

+2


source


In addition to 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 your ajax setup doesn't have withCredentials

u password

and u 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'
});

      

+1


source







All Articles