2016-07-13 8 views
1

magento APIにアクセスするために私のアプリケーション内でトークン認証を使用しています。 I郵便配達で、次の設定を行うと、それが正常に動作します: enter image description hereMagento 2トークン認証 - 400エラー/ CORSの問題

しかし、プリフライトのためのHTTP動詞オプションをサポートしていないようだと、私は一貫して戻って400エラーを取得するjQueryのポストを使用して(私は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いくつかの私の$:ここ

enter image description here

は、いくつかのcURLの応答です:

{"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" \ 
    -d '{"username": "ember-app", "password": "ember-app2"}'\ 
    -X OPTIONS --verbose https://myhost/index.php/rest/V1/integration/admin/token 

がある応答を与えます

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 

しかし、通常のカールポストを行うと、正常に動作します:それは最初のリソースを提供しています1とは異なるドメインからリソースを要求すると

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

さらに '$の.post( 'MYIP/index.phpを/休憩/ V1 /統合/管理/トークン?ユーザ名=燃えさしアプリ&パスワード=燃えさし-APP2'、機能(応答){ はconsole.log(あなたはCORSエラーを返すURLにGETを引き起こします – rickyduck

+0

NginxのCORS設定を共有することもできますか? – HiDeo

答えて

4

要求は、クロスオリジンのHTTPリクエストとして識別されます。セキュリティ上の理由から、スクリプト内から開始されるクロスオリジンHTTPリクエストはブラウザでは制限されています。

W3Cのクロスソースリソース共有(CORS)メカニズムは、Webサーバーにクロスドメインアクセス制御を提供し、セキュアなドメイン間データ転送を可能にする標準を定義しています。新しいHTTPヘッダーを追加することで、サーバーがWebブラウザーを使用してその情報にアクセスすることが許可されているオリジンのセットを定義することができます。

さらに、一部のHTTP要求は、ユーザーデータを変更できるときにデフォルトで非セキュアと見なされます。これらのリクエストは、ウェブブラウザで自動的にのプリフライトになります。これは、リクエストが送信される前に、プリフライトリクエストがOPTIONS動詞でブラウザから他のドメインサーバに送信され、実際のリクエストが安全かどうかを判断することを意味します。サーバーからの承認が得られたら、実際の要求が送信されます。

あなたがPostmanを使用しているときは、実際のリクエストが送信され、それがそれです。 CORSの保護はありません。郵便配達はウェブブラウザではありません。それだけで動作します。

jQueryを使用してWebブラウザからスクリプトでAJAX呼び出しを行うと、CORS標準に準拠し、リクエストが安全でないことを意味します。つまり、preflight である必要があります。 OPTIONSメソッドを使用してサーバーに最初のリクエストを送信し、実際のリクエストが安全かどうかを確認します。これらのリクエストはあなたのWebサーバー(Nginxのようです)で許可される必要があります。

NginxでCORSを有効にする方法についてthis exampleをチェックして、実際の設定と比較することができます。基本的なワイドオープン構成は(私はいくつかのコメントを追加しました)のようになります。

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); 
}) 
+0

あなたの答えに感謝します。これはnginxのために使った設定です。実際には、APIの他の部分へのCORSリクエストはうまくいきます(例えば、 '/ rest/V1/guest-carts /'が正常に動作します)。 – rickyduck

+0

すべてのAPIエンドポイントでhttpsを使用していますか? myhost/index.php/rest/V1/guest-carts/'または認証に関連するエンドポイントのみ – HiDeo

+0

彼らはすべてHTTPSを使用しています。チャットを設定した場合は、URLを渡して自分で見ることができます – rickyduck

0

この例では、CORSエラーは赤いニシンのようです。

トークンの生成に使用されるMagentoエンドポイント/V1/integration/admin/tokenがあります。

アプリ内でこれを使用する必要はありません。

代わりに、これは複数のステップのプロセスです。

  1. 任意のWeb APIリクエストのための店、configファイル内のトークン

  2. トークン http://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-token.html#auth-request

  3. を生成Bearer HTTP認可スキームでAuthorizationリクエストヘッダー内のトークンを指定します。 http://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-token.html#web-api-access

0

のMagentoのルートフォルダに存在するMagentoの.htaccessファイル内の行、下に含めます。それは私のために働いた。

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]