为什么我的Drupal 8 CORS设置不起作用?

时间:2017-07-20 09:07:00

标签: jquery ajax drupal cors drupal-8

自Drupal 8.2以来,cors的设置就是核心。在我的services.yml(和default.services.yml)中,我有以下设置:

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

我的域a.com受密码保护。

在域b.com上,我尝试从域a.com加载一些API:

$.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'
});

在Chrome中它工作正常,在Firefox中我收到错误。请求标头:

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

响应是401“需要授权”,它说请求方法是OPTIONS(?)。

这里有什么问题?

insomnia中执行相同的请求完全正常。

2 个答案:

答案 0 :(得分:2)

  

响应是401“需要授权”,它说请求方法是OPTIONS(?)。

您需要将服务器后端配置为不需要OPTIONS请求的授权。

401响应表明服务器需要授权OPTIONS请求,但授权失败,因为请求不包含所需的凭据。

原因是,OPTIONS请求由您的浏览器自动发送,作为CORS的一部分。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests一般解释为什么浏览器会进行CORS预检OPTIONS请求,但在问题的具体情况下,原因是请求包含Authorization请求标头。

所发生的事情是:

  1. 您的代码告诉您的浏览器,它希望使用Authorization标题发送请求。
  2. 您的浏览器说,好的,带有Authorization标头的请求要求我执行CORS预检OPTIONS,以确保服务器允许使用Authorization标头的请求。
  3. 您的浏览器会将OPTIONS请求发送到服务器而没有Authorization标题,因为OPTIONS检查的全部目的是查看是否可以包括那个标题。
  4. 您的服务器看到OPTIONS请求,但不会以指示它允许请求中的Authorization标头的方式对其进行响应,而是由于缺少标头而拒绝它,因为它没有标头。
  5. 您的浏览器需要200或204的CORS预检响应,而是获得401响应。因此,您的浏览器就会停在那里,并且永远不会尝试代码中的GET请求。
  6. 因此,您需要弄清楚当前服务器端代码的哪一部分导致您的服务器需要OPTIONS个请求的授权,并且您需要对其进行更改,以便它改为处理OPTIONS个请求未经授权不得。

    解决问题后,问题中显示的现有cors.config应该会导致服务器以正确的方式响应OPTIONS请求 - Access-Control-Allow-Headers响应标头包含{ {1}},以便您的浏览器可以说,好的,此服务器允许包含Authorization标头的跨源请求,因此我现在继续发送实际的Authorization请求。

答案 1 :(得分:1)

除了正常工作的CORS配置和htaccess设置:

SetEnvIfNoCase Request_Method OPTIONS noauth
Order Deny,Allow
Deny from all
Require valid-user
Allow from env=noauth
Satisfy Any

您必须确保您的ajax设置没有withCredentials以及passwordusername,就像在我的问题中一样。至少这会导致Firefox出错。工作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'
});