API Gateway CORS:「Access-Control-Allow-Origin」ヘッダーなし


102

CORSはAPIGatewayを介して設定され、Access-Control-Allow-Originヘッダーが設定されていますが、Chrome内でAJAXからAPIを呼び出そうとすると、次のエラーが発生します。

XMLHttpRequestはhttp://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYYを読み込めません。要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン 'null'はアクセスを許可されません。応答のHTTPステータスコードは403でした。

Postmanを介してURLを取得しようとしましたが、上記のヘッダーが正常に渡されたことが示されています。

渡されたヘッダー

そして、オプションの応答から:

応答ヘッダー

JSON-Pに戻さずにブラウザからAPIを呼び出すにはどうすればよいですか?


S3にセットアップしましたか?もしそうなら、あなたは我慢できますBucket Policyか?ポリシーにメソッドがあることを確認してください
iSkore 2016

10
APIゲートウェイチームはこちら...コンソールで「CORSを有効にする」機能を使用する場合、構成は正しいはずです。私の推測では、ブラウザが実行しているJavaScriptのAPIで正しいリソースパスを呼び出していない可能性があります。存在しないメソッド/リソース/ステージに対してAPI呼び出しを行おうとすると、CORSヘッダーのない汎用403を受け取ります。PostmanのOPTIONS呼び出しには明らかにすべての適切なCORSヘッダーが含まれているため、適切なリソースを呼び出している場合、ブラウザーがAccess-Control-Allow-Originヘッダーを見逃す可能性があるかどうかはわかりません。
jackko 2016

1
@ RyanG-AWSクライアントは、APIがユーザー固有のトークンを使用して呼び出すリソースによって認証されるため、リクエストに署名していません。したがって、認証情報は要因ではありません。ブラウザで直接URLにアクセスしてAPIを呼び出すと、適切な応答が得られます。
タイラー

2
@makinbacon:これに対する解決策を見つけましたか?私はここで同じ問題を経験しています。
Nirmal 2016

1
私のメソッドとステージはLambdaによって自動的に生成されました。事後にCORSを有効にしました。OPと同じエラー。自動生成されたものを吹き飛ばし、新しいAPIとメソッドを作成し、新しいステージにデプロイしましたが、正常に機能しました。
火傷2016

回答:


117

同じ問題が発生します。私は見つけるために10時間を使用しました。

https://serverless.com/framework/docs/providers/aws/events/apigateway/

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};

私も抱えていた問題を修正しました。ご回答ありがとうございます!
エリックブラウン

サーバーレスは使用していませんが、これで問題は解決しました。これらのヘッダーを実際のソースから渡す必要があると思います。
コスタ

2
参考までに、ここに示した例には問題があります。「Access-Control-Allow-Credentials」:trueがある場合、Access-Control-Allow-Originのワイルドカード*を使用することはできません。このルールはブラウザによって適用されます。ここここを
ケビン

1
これは機能していません。同じエラーが表示されます。リクエストヘッダーフィールドaccess-control-allow-credentialsは、プリフライト応答のAccess-Control-Allow-Headersでは許可されていません。
mitesh71 7219年

1
興味のある方は、これに言及している公式ドキュメントをご覧ください:docs.aws.amazon.com/apigateway/latest/developerguide/… > LambdaまたはHTTPプロキシ統合の場合でも、APIGatewayで必要な> OPTIONS応答ヘッダーを設定できます。ただし、プロキシ統合では統合応答が無効になっているため、Access-Control-Allow-Originヘッダーを返すにはバックエンドに依存する必要があります。
LeonidUsov19年

104

他の誰かがまだこれに遭遇している場合-私は私のアプリケーションの根本原因を突き止めることができました。

カスタムオーソライザーを使用してAPI-Gatewayを実行している場合-API-Gatewayは、実際にサーバーに到達する前に401または403を送り返します。デフォルト-カスタム認証者から4xxを返す場合、API-GatewayはCORS用に構成されていません。

また、API Gatewayを介して実行されているリクエストのステータスコードを取得している場合、0または1リクエストから取得している場合は、おそらくこれが問題です。

修正するには、API Gateway構成で、「Gateway Responses」に移動し、「Default 4XX」を展開して、そこにCORS構成ヘッダーを追加します。すなわち

Access-Control-Allow-Origin: '*'

ゲートウェイを再デプロイしてください-そして出来上がり!


7
わたしは、あなたを愛しています。これに真剣に2日間取り組んでいます。
efong5 2018年

4
AWS CLIでこれをやりたいと思ったものについては、使用:aws apigateway update-gateway-response --rest-api-id "XXXXXXXXX" --response-type "DEFAULT_4XX" --patch-operations op="add",path="/responseParameters/gatewayresponse.header.Access-Control-Allow-Origin",value='"'"'*'"'"'
ウィル

1
私はカスタムオーソライザーを使用していませんが、リクエストに不正なJSONが含まれていたため、これが必要でした-ありがとうございます!
フォースヒーロー

9
私自身に注意してください
後で

2
奇妙なことに、これは私にとってはうまくいきましたが、再デプロイする必要はありませんでした。以前に再デプロイしてみました。なぜそれが私のために働いたのか分かりません。
マイケル

19

1) @riseresやその他の変更と同じことを行う必要がありました。これは、私の応答ヘッダーです。

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

2)そして

このドキュメントによると:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

API Gateway構成でラムダ関数にプロキシを使用する場合、postメソッドまたはgetメソッドにはヘッダーが追加されず、オプションのみが追加されます。応答(サーバーまたはラムダ応答)で手動で行う必要があります。

3)そして

その上、APIゲートウェイのpostメソッドで「APIKeyRequired」オプションを無効にする必要がありました。


5
はい、私たちの多くが最初に見逃している微妙なことは、「Lambdaプロキシ統合を使用する」を使用してLambda関数のAPI Gateway統合を構成したら、あなたや他の人が述べているように実行し、ヘッダーが追加されていることを確認する必要があることですラムダの応答でプログラム的に。APIゲートウェイで「CORSを有効にする」によって作成され、OPTIONSレスポンダーを作成する自動生成機能は優れていますが、API内の統合リクエストで「ラムダプロキシ統合を使用する」を設定した場合は、そこまで到達できません。ゲートウェイ。

1
これは私にとってはうまくいきました...マニュアルを正しく読んだ後:重要プロキシ統合のANYメソッドに上記の手順を適用すると、該当するCORSヘッダーは設定されません。代わりに、バックエンドはAccess-Control-Allow-Originなどの該当するCORSヘッダーを返す必要があります。 docs.aws.amazon.com/apigateway/latest/developerguide/...
BennyHilarious

14

この問題に関するすべてを無駄に試した場合、私が行った場所に行き着くでしょう。結局のところ、Amazonの既存のCORSセットアップ手順は問題なく機能します...再デプロイすることを忘れないでください!CORS編集ウィザードは、小さな緑色のチェックマークがすべて付いていても、APIをライブで更新しません。おそらく明らかですが、それは私を半日困惑させました。

ここに画像の説明を入力してください


これでした。文字通り2日間これに取り組んでいます。ゲートウェイを編集した後、少なくとも再デプロイを要求しないロジックがわからない。
クリスクリステンセン

何かが信じられないほど、このような問題について倒しまだ緩和するように、常にあります-あなたはそれを考え出しました喜ん@ChrisChristensen
レーザ発振

これは2020年に有効な答えです。ありがとう
Rahul Khanna

RE-DEPLOY RE-DPLOY RE-DEPLOY
Surjith SM

11

私は:私のサンプルの作業手に入れただけで挿入された「アクセス制御-許可-起源」:「*」、内側の{}:ヘッダをラムダ関数nodejs生成に。Lambdaで生成されたAPIレイヤーに変更を加えませんでした

これが私のNodeJSです:

'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

これが私のAJAX呼び出しです

$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});

「../latest/ ..」パスフラグメントがあっても、Amazonのドキュメントの多くが古くなっていることがわかりました。約1週間前にすべてを廃棄した後、CORSボタンが突然正常に機能していると表示されました。APIは「ANY」メソッドを自動的に作成し、CORSボタンは「OPTIONS」メソッドを自動的に作成しました。APIには何も追加しませんでした。上記の「GET」は機能します。その後、APIに触れることなく機能するajax「POST」を追加しました。
mannyC 2017年

AWSコンソールを使用してメソッド応答にAccess-Control-Allow-Originを追加する方法を理解するために、ほぼ2時間費やしましたが、これも私にとって有効な唯一のことでした。
Shn_Android_Dev

8

Google社員の場合:

理由は次のとおりです。

  • 単純なリクエスト、または、GET/ POSTCookieなしではプリフライトはトリガーされません
  • パスにCORSを設定すると、API GatewayはOPTIONSそのパスのメソッドのみを作成し、Allow-Originユーザーが呼び出したときにモック応答を使用してヘッダーを送信しますがOPTIONSGET/POSTAllow-Origin自動的に取得されません
  • CORSモードをオンにして単純なリクエストを送信しようとすると、その応答にAllow-Originヘッダーがないため、エラーが発生します
  • ベストプラクティスに従うことができます。単純なリクエストはユーザーに応答を送信することを意図したものではなく、リクエストと一緒に認証/ Cookieを送信して「シンプルではない」ようにし、プリフライトがトリガーされます
  • それでも、次のリクエストでは、CORSヘッダーを自分で送信する必要があります OPTIONS

要約すると:

  • 無害なものだけがAPIGatewayOPTIONSによって自動的に生成されます
  • OPTIONSパス上のCORSの可能性をチェックするための予防措置としてブラウザでのみ使用されます
  • かどうかCORSをされ受け入れられた実際のメソッドなどに依存しますGET/POST
  • 応答で適切なヘッダーを手動で送信する必要があります

5

ラムダ関数の応答にヘッダーを追加したところ、魅力のように機能しました

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hey it works'),
        headers:{ 'Access-Control-Allow-Origin' : '*' }
    };
    return response;
};

4

私は内に簡単な解決策を見つけました

APIゲートウェイ> APIエンドポイントを選択>メソッドを選択(私の場合はPOSTでした)

ドロップダウンアクション> CORSを有効にする..それを選択します。

次に、ドロップダウンアクションを再度選択します> APIをデプロイします(再デプロイします)

ここに画像の説明を入力してください

出来た !


なぜこの回答は反対票を投じられたのですか?しかし、他にも同様の回答がありますか?
DineshKumar19年

AWSベースのAPIゲートウェイ呼び出しの場合、このソリューションは機能します
ewalel

3

ラムダオーソライザーが失敗し、何らかの理由でCORSエラーに変換されていることに気付いた後、私は仕事を始めました。私のオーソライザー(および最初に追加すべきいくつかのオーソライザーテスト)への簡単な修正とそれは機能しました。私にとっては、APIGatewayアクション「EnableCORS」が必要でした。これにより、APIに必要なすべてのヘッダーとその他の設定が追加されました。


そして再デプロイ!:)
ロビンCサミュエル

3

私にとって、最終的に機能した答えは、Alex Rの答え(2番目に賛成)からのJamesShapiroからのコメントでした。そもそも、S3でホストされている静的ウェブページを取得してラムダを使用してcontact-usページを処理し、メールを送信しようとして、このAPIGatewayの問題に直面しました。[]デフォルトの4XXをチェックするだけで、エラーメッセージが修正されました。

ここに画像の説明を入力してください


このメニューはどこにありますか?どこにも見当たりません。
ニックH

@NickHはRaviRamの写真を見てください。[アクション]の下に[CORSを有効にする]という項目があり、それを選択するとメニューが表示されます。
ジェイソン

2

関数またはコードを変更した後次の2つの手順に従います。

最初にCORSを有効にし、次に毎回APIをデプロイします


有難うございます。リソースの「EnableCORS」に気づきませんでした。頭がおかしくなった。
Shlomi Bazel

2

両方POSTでCORSを有効にした後でコードをデプロイし、OPTIONS私のために働きました。


1
あなたの貢献に感謝します、しかしあなたはそれがあなたのために働いた理由を説明できますか?私はあなたの答えを改善するためにこのガイドを読むことを勧めます:「私が良い答えを書く方法」ここで:stackoverflow.com/help/how-to-answer
ギヨームレイモンド

1

私は実行していますがaws-serverless-express、私の場合は編集する必要がありますsimple-proxy-api.yaml

CORSがに設定される前https://example.comに、サイトの名前を入れ替えて、を介して再デプロイしたところnpm run setup、既存のラムダ/スタックが更新されました。

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...

1

私の場合、API Gatewayの承認メソッドとしてAWS_IAMを使用していたため、エンドポイントにアクセスするためのIAMロール権限を付与する必要がありました。


2
このコメントを残してよかったです。これは私に起こり続けます:D。
CamHart

私は将来再発する問題に対する自分自身の解決策を見つけるのが大好きです。
ザックグリアー

0

この問題のもう1つの根本的な原因は、HTTP /1.1とHTTP / 2の違いである可能性があります。

症状:すべてではない一部のユーザーが、ソフトウェアの使用時にCORSエラーを受け取ると報告しました。

問題:Access-Control-Allow-Originヘッダが欠落していました、時々

コンテキスト:ホワイトリストへの照合OPTIONSなど、リクエストの処理と対応するCORSヘッダーでの返信専用のLambdaを用意しました。Access-Control-Allow-OriginOrigin

解決策: API Gatewayは、HTTP / 2呼び出しではすべてのヘッダーを小文字に変換しているようですが、HTTP /1.1では大文字を使用しています。これにより、アクセスevent.headers.originが失敗しました。

この問題も発生しているかどうかを確認してください。

APIがにhttps://api.example.comあり、フロントエンドがにあると仮定しますhttps://www.example.com。CURLを使用して、HTTP / 2を使用してリクエストを行います。

curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

応答出力にはヘッダーを含める必要があります。

< Access-Control-Allow-Origin: https://www.example.com

HTTP / 1.1を使用して(または小文字のOriginヘッダーを使用して)同じ手順を繰り返します。

curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

Access-Control-Allow-Originヘッダーが欠落している場合は、ヘッダーを読み取るときに大文字と小文字の区別を確認することをお勧めしますOrigin


0

他のコメントに加えて、注意すべき点は、基礎となる統合から返されるステータスと、そのステータスに対してAccess-Control-Allow-Originヘッダーが返されるかどうかです。

'Enable CORS'を実行すると、200ステータスしか設定されません。エンドポイントに他のユーザー(4xxや5xxなど)がある場合は、ヘッダーを自分で追加する必要があります。


-2

私の場合、フェッチリクエストのURLを間違って書いていました。でserverless.yml、次のように設定corstrueます。

register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

次にラムダハンドラーでヘッダーを送信しますが、フロントエンドでフェッチリクエストを間違えると、レスポンスでそのヘッダーを取得できず、このエラーが発生します。そのため、前面にあるリクエストURLを再確認してください。


-3

Pythonでは、以下のコードのようにそれを行うことができます。

{ "statusCode" : 200,
'headers': 
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': "*"
     },
"body": json.dumps(
    {
    "temperature" : tempArray,
    "time": timeArray
    })
 }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.