我在我的应用中使用令牌身份验证来访问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); }
);
我还在对象周围尝试过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
给出的答案是:
{"message":"Request method is invalid."}
同样:
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
然而,正常的卷曲工作正常:
curl -H "Content-Type: application/json" -X POST -d '{"username":"ember-app","password":"ember-app2"}' https://myhos/index.php/rest/V1/integration/admin/token
答案 0 :(得分:5)
当请求来自与服务第一资源的域不同的域请求资源时,将该请求标识为跨源HTTP请求。出于安全原因,在脚本中发起的跨源HTTP请求在浏览器中受到限制。
W3C的跨域资源共享(CORS)机制定义了一种标准,该标准为Web服务器提供跨域访问控制,以实现安全的跨域数据传输。它的工作原理是添加新的HTTP标头,允许服务器使用Web浏览器定义允许访问该信息的起源集。
此外,一些HTTP请求在修改用户数据时默认为非安全。这些请求在Web浏览器中自动预检。这意味着在发送请求之前,浏览器会将带有OPTIONS
谓词的预检请求发送到其他域服务器,以确定实际请求是否可安全发送或不。经服务器批准后,将发送实际请求。
当您使用邮递员时,您的实际请求会被发送。没有CORS保护或任何东西,Postman不是一个Web浏览器。它只是有效。
当您使用jQuery在Web浏览器的脚本中进行AJAX调用时,它将遵循CORS标准并标记您的请求是不安全的,这意味着它应该预检< / em>的。然后,它会使用OPTIONS
方法向您的服务器发送第一个请求,以检查您的实际请求是否安全。需要在您的Web服务器(似乎是Nginx)上允许这些请求。
您可以查看this example如何在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';
}
}
如果服务器端的所有内容都是有序的,那么您应该调整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);
})
答案 1 :(得分:0)
在这种情况下看起来CORS错误是一个红色的鲱鱼。
您提到用于令牌生成的Magento端点/V1/integration/admin/token
。
您无需在自己的应用中使用此功能。
相反,这可以是一个多步骤的过程。
将令牌存储在配置文件中
对于任何Web API请求,请在Authorization
请求标头中使用Bearer
HTTP授权方案指定令牌。
http://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-token.html#web-api-access
答案 2 :(得分:0)
在Magento .htaccess文件中包含以下行,该文件位于Magento的根文件夹中。它对我有用。
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
# Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]