Magento 2 Token Auth - 400错误/ CORS问题

ric*_*uck 1 ajax jquery magento cors

我在我的应用程序中使用令牌身份验证来访问magento API.我在postman中进行以下设置,它运行正常: 在此输入图像描述

然而,使用jQuery帖子我一直得到400错误,因为它似乎不支持预检的HTTP动词OPTIONS(我有一个针对nginx的CORS配置).我试过了:

$.ajax({
  method: "POST",
  url: `myip/index.php/rest/V1/integration/admin/token`,
  data: {username: 'ember-app', password: 'ember-app2'},
}).done(function(response) {
  alert(response);
});

$.ajax({
  method: "POST",
  url: `myip/index.php/rest/V1/integration/admin/token?username=ember-app&password=ember-app2`
}).done(function(response) {
  alert(response);
});

$.post(
  'myip/index.php/rest/V1/integration/admin/token', 
  {username: 'ember-app', password: 'ember-app2'},
  function(response) { alert(response); }
);
Run Code Online (Sandbox Code Playgroud)

我还在对象周围尝试了JSON.stringify.为什么它在邮递员中工作但在xhr我经常得到400错误?此外,该请求然后触发另一个GET请求,返回一个cors错误.一些我的$ .post在控制台中导致这种情况:

在此输入图像描述

以下是一些cURL回复:

curl -H "Origin: http://localhost:4200" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: X-Requested-With" \
  -d '{"username": "ember-app", "password": "ember-app2"}'\
  -X OPTIONS --verbose https://myhost/index.php/rest/V1/integration/admin/token
Run Code Online (Sandbox Code Playgroud)

给出一个响应:

{"message":"Request method is invalid."} 
Run Code Online (Sandbox Code Playgroud)

与:相同:

curl -H "Origin: http://localhost:4200" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: X-Requested-With" \
  -X OPTIONS --verbose https://myhost/index.php/rest/V1/integration/admin/token?username=ember-app&password=ember-app2
Run Code Online (Sandbox Code Playgroud)

但是,正常的卷曲工作正常:

curl -H "Content-Type: application/json" -X POST -d '{"username":"ember-app","password":"ember-app2"}' https://myhos/index.php/rest/V1/integration/admin/token
Run Code Online (Sandbox Code Playgroud)

HiD*_*Deo 5

当请求从与服务第一资源的域不同的域请求资源时,该请求被标识为跨源HTTP请求.出于安全原因,在脚本中发起的跨源HTTP请求在浏览器中受到限制.

来自W3C的跨源资源共享(CORS)机制定义了一种标准,该标准为Web服务器提供跨域访问控制,以实现安全的跨域数据传输.它的工作原理是添加新的HTTP标头,允许服务器使用Web浏览器定义允许访问该信息的起源集.

此外,某些HTTP请求在修改用户数据时默认为非安全.这些请求会自动在Web浏览器中进行预检.这意味着在发送请求之前,浏览器会将带有动词的预检请求OPTIONS发送到其他域服务器,以确定实际请求是否可以安全发送.经服务器批准后,将发送实际请求.

当您使用邮递员时,您的实际请求将被发送,就是这样.没有CORS保护或任何东西,Postman不是一个Web浏览器.它只是有效.

当您使用jQuery在Web浏览器的脚本中进行AJAX调用时,它将遵循CORS标准并标记您的请求是不安全的,这意味着它应该是预检.然后,它会向您的服务器发送第一个请求,并使用该OPTIONS方法检查您的实际请求是否安全.需要在您的Web服务器(这似乎是Nginx)上允许这些请求.

您可以查看此示例,了解如何在Nginx上启用CORS,并将其与您的实际配置进行比较.一个基本的开放式配置(我添加了一些评论):

location / {
  // OPTIONS requests.
  if ($request_method = 'OPTIONS') {
    // URI that may access the resource.
    add_header 'Access-Control-Allow-Origin' '*';

    // Methods allowed when accessing the resource.
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

    // Headers that can be used when making the actual request.
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

    // Cache the preflight result for 20 day.
    add_header 'Access-Control-Max-Age' 1728000;

    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;

    return 204;
  }

  // POST requests.
  if ($request_method = 'POST') {
    // URI that may access the resource.
    add_header 'Access-Control-Allow-Origin' '*';

    // Methods allowed when accessing the resource.
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

    // Headers that can be used when making the actual request.
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  }

  // GET requests
  if ($request_method = 'GET') {
    // URI that may access the resource.
    add_header 'Access-Control-Allow-Origin' '*';

    // Methods allowed when accessing the resource.
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

    // Methods allowed when accessing the resource.
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  }
}
Run Code Online (Sandbox Code Playgroud)

如果服务器端的所有内容都是有序的,则应调整jQuery请求以匹配服务器上的预期.

jQuery.ajax({
  url: 'https://host/rest/V1/integration/admin/token',
  data: JSON.stringify({"username": "ember-app", "password": "ember-app2"}),
  contentType: "application/json",
  method: 'POST'
}).done((response) => {
  alert(response);
})
Run Code Online (Sandbox Code Playgroud)